如何在 replaceWith 之后重新绑定 jQuery 事件处理程序,例如在使用 Optimizely 时
How to rebind jQuery event handlers after replaceWith, e.g when using Optimizely
优化 A/B 测试服务广泛使用.replaceWith("new HTML")
来生成简单的 A/B 测试。这会产生从替换元素中删除侦听事件的任何事件侦听器的副作用,即使新元素具有相同的 ID/类也是如此。
例:
-
DOM 包含:
<div class="something"> <button id="myButton"></button> </div>
-
已听:
$("#myButton").click(function() { console.log('clicked!'); });
-
替换为:
$(".something").replaceWith("some new HTML, containing #myButton");
在第 3 步之后,点击 #myButton
不再起作用,因为原始 DOM 元素已被销毁并添加了一个新的元素。
解决这个问题的好方法和"干净"的方法是什么?
可能的解决方案
- 了解您的代码库并在 Optimizely 的实验中"重新添加"适当的事件侦听器。
- 问题:A/B测试人员可能不是真正的软件开发人员,认为这很麻烦。
- 似乎不是一个很干净的方式
-
找到一种在 Optimizely 之后执行代码的方法,以这种方式添加所有事件侦听器。有没有好方法可以做到这一点?
-
使用"使用 $.on() 的事件委托",如下所述:如何用 jQuery 替换 HTML 但保留事件绑定
- 问题:很难预测究竟会测试和替换 A/B 的内容
编辑:我正在使用jQuery 1.11.x
我不确定是否有一种"干净"的方法可以做到这一点,因为附加到旧元素的事件可能不适用于新元素。想象一下,一个表单元素被div 替换:onchange
或onblur
事件应该发生什么?
优化尝试同时迎合两种不同类型的用户:高级用户和新手。所见即所得不能做复杂的变化,所以如果你正在编辑代码,那么你应该知道你在做什么。
一般而言,这意味着上面的选项1。两种合理的方法是:
- 将旧元素转换为新元素,而不仅仅是替换它 隐藏旧元素,
- 添加新元素,然后将事件从新元素代理到旧元素
当然,除非主代码库是将事件与事件委托绑定,在这种情况下,保持相同的 ID/类就足够了。如果您可以访问原始代码库(对于在 Optimizely 编辑器中工作的人来说,情况通常并非如此 - 我为最大的第三方测试机构工作,我们无法对客户的实际代码库进行任何更改),那么无论如何您都应该升级到事件委派。
如果您有权访问主站点代码,那么您当然可以创建一个附加到窗口的回调(Optimizely 作用域它的所有代码),您的 Optimizely 代码在完成后调用该回调,但同样,事件委派可能是一个更好的选择。
当你说你正在使用jQuery 1.11.x时,你是指在你的网站上,还是Optimizely包含什么?如果 Optimizely 包含什么,它是修剪版本还是完整版本(优化项目主页-->设置-->Javascript)?
你不应该使用 jQuery 的 onRemove() 来首先为 Optimizely 的"魔术"后面发生的事件设置侦听器,例如2200494?
- keyup事件处理程序更改焦点不适用于快速键入
- 提示使用服务器端事件处理程序激活JavaScript
- 将事件处理程序绑定到任何可能的事件
- 正在将事件处理程序添加到不存在的类
- 在循环中附加事件处理程序时出现浏览器性能问题
- 在同一个javascript事件处理程序中调用不同的函数
- 有没有一种方法可以让内联事件处理程序在元素创建后立即执行
- 检查事件处理程序参数
- 实现延迟的jquery更改事件处理程序
- 如何使用Node.js在JavaScript模块文件之间使用事件处理程序
- 如何使jQuery的“bind”或“on”事件处理程序幂等
- 带有参数的Javascript事件处理程序
- Jquery事件处理程序仅适用于匿名函数
- 如何从另一个处理程序内部取消JavaScript事件处理程序函数的执行
- 如何在jQuery事件处理程序中存储和重用超时
- 如何向onClick事件处理程序传递一个接受参数的函数,并且仍然将该函数绑定到组件's”;这个“;上下文
- 异步处理所有事件处理程序的方法
- jsplumb中的Click事件处理程序丢失“;这个“;对象
- 构造函数中的事件处理程序与构造函数外的事件处理函数的行为不同
- 如何在事件处理程序的回调中防止Default