如何将内联 javascript 事件与其 HTML 元素完全解除绑定?
我试过了:
- 从 body 元素取消对事件的委托
- 解除事件与元素的绑定
- 甚至从 HTML 元素中删除 event 属性
至少令我惊讶的是,只有删除onchange
属性 ( .removeAttr('onchange')
) 才能防止事件再次触发。
<input type="text" onchange="validateString(this)"></input>
我知道这对代表来说是可能的,这可能是最好的方法,但只是在这里玩。这个例子纯粹是为了提出问题而假设的。
所以假设的情况是这样的:
我正在编写一个 javascript 验证库,该库通过内联 HTML 属性将 javascript 事件绑定到输入字段,如下所示:
<input type="text" onchange="validateString(this)"></input>
但是,我想通过解除绑定我的事件来使库更好一点,这样在单页应用程序中使用这个库的人就不必管理我的事件处理程序,也不必混乱他们的代码通过将输入事件连接到我假设的验证库中的函数......无论如何。这些都不是真的,但它似乎是一个不错的用例。
这是假设验证 Library.js 的“示例”代码:
http://jsfiddle.net/CoryDanielson/jwTTf/
要进行测试,只需在文本框中输入,然后单击其他地方来触发更改事件。在“时间轴”选项卡上打开并记录 Web 检查器来执行此操作。突出显示与您触发 change 事件(多次触发 change 事件)相关的时间线区域,您将看到事件侦听器(在下面的窗口中)在每个 change 事件上增加 100。如果正确管理和删除,每个事件侦听器都会在呈现新输入之前被正确删除,但我还没有找到一种方法来使用内联 javascript 事件正确地做到这一点。
该代码的作用是:
- onChange,输入元素触发验证功能
- 该函数验证输入并在成功时为边框着色
然后在 1 秒后(为了演示内存泄漏),输入元素连续 100 次替换为相同的 HTML,而没有取消绑定更改事件(因为我不知道该怎么做……这就是问题所在)。这模拟了在单页应用程序中更改视图。这会在 DOM 中创建 100 个新的事件侦听器,这些事件侦听器可以通过 Web 检查器看到。
- 有趣的笔记。
$('input').removeAttr('onchange');
实际上会阻止 onchange 事件在未来被触发,但不会垃圾收集 web 检查器中可见的 eventListener/DOM 内容。
- 有趣的笔记。
此屏幕截图是在更改事件触发 3 次之后。每次,100 个新的 DOM 节点都使用相同的 HTML 呈现,我尝试onchange
在替换 HTML 之前从每个节点取消绑定事件。
更新:我回到这个问题,只是使用 JSFiddle 做了一个快速的小测试,以确保答案是有效的。我运行了数十次“测试”,然后等待——果然,GC 通过并处理了事务。