从内存中的HTML元素取消绑定内联javascript事件

从内存中的HTML元素取消绑定内联javascript事件,javascript,jquery,html,memory-leaks,Javascript,Jquery,Html,Memory Leaks,如何完全解除内联javascript事件与HTML元素的绑定? 我试过: 从body元素取消对事件的授权 解除事件与元素的绑定 甚至从HTML元素中删除事件属性 至少令我惊讶的是,只有删除onchange属性(.removeAttr('onchange'))才能防止事件再次触发 <input type="text" onchange="validateString(this)"></input> 我知道这对代表们来说是可能的,这可能是最好的方式,但在这里就这么做

如何完全解除内联javascript事件与HTML元素的绑定?

我试过:

  • 从body元素取消对事件的授权
  • 解除事件与元素的绑定
  • 甚至从HTML元素中删除事件属性
至少令我惊讶的是,只有删除
onchange
属性(
.removeAttr('onchange')
)才能防止事件再次触发

<input type="text" onchange="validateString(this)"></input>

我知道这对代表们来说是可能的,这可能是最好的方式,但在这里就这么做吧。这个例子纯粹是为了提出问题而假设的


所以假设的情况是:

我正在编写一个javascript验证库,该库通过内联HTML属性将javascript事件绑定到输入字段,如下所示:

<input type="text" onchange="validateString(this)"></input>

但是,我希望通过取消绑定我的事件使库变得更好,这样在单页应用程序中使用此库的用户就不必管理我的事件处理程序,也不必通过将输入事件连接到我假设的验证库中的函数来使代码变得混乱。。。无论什么这些都不是真的,但它似乎是一个不错的用例。

以下是假设验证库.js的“示例”代码:

要进行测试,只需在文本框中键入,然后单击其他位置即可触发更改事件。在打开web inspector并在“时间轴”选项卡上录制的情况下执行此操作。突出显示与触发更改事件(多次触发更改事件)相关的时间线区域,您将看到每个更改事件的事件侦听器(在下面的窗口中)增加100。如果管理和删除得当,每个事件侦听器在呈现新输入之前都会被正确删除,但我还没有找到一种方法来正确处理内联javascript事件

该代码的作用是:

  • 一旦更改,输入元素就会触发一个验证函数
  • 如果成功,该函数将验证输入并为边框着色
  • 然后在1秒后(为了演示内存泄漏),输入元素被替换为相同的HTML,一行替换100次,而不解除更改事件的绑定(因为我不知道怎么做..这就是问题所在)。这模拟在单个页面应用程序中更改视图。这将在DOM中创建100个新的EventListener,这可以通过web检查器看到

    • 有趣的音符<代码>$('input')。removeAttr('onchange')实际上会防止将来触发onchange事件,但是不会垃圾收集web检查器中可见的eventListener/DOM内容
  • 此屏幕截图是更改事件触发3次后的屏幕截图。每次,100个新的DOM节点都使用相同的HTML呈现,我尝试在替换HTML之前从每个节点解除
    onchange
    事件的绑定


    更新:我回到这个问题,只是使用JSFIDLE做了一个快速的小测试,以确保答案是有效的。我运行了几十次“测试”,然后等待——果不其然,GC通过并处理了业务


    我的第一个建议是使用
    off('change')
    ,但您似乎已经尝试过了。它不工作的原因可能是处理程序没有附加
    .on('change')
    。我不太了解jQuery如何在内部处理这样的侦听器,但请尝试附加
    .on('change',function()…
    .bind('change',function())…
    相反。

    我认为您无需担心。尽管内存不再被引用,最终将被垃圾收集,但它仍然显示在Web Inspector内存窗口中。当GC决定垃圾收集内存时,内存将被垃圾收集(例如,当浏览器内存不足或在某个固定时间之后)。详细信息由GC实现者决定。您只需单击“收集垃圾”即可验证这一点按钮。我正在运行Chrome 23,当我在你的验证框中输入文本大约5到6次后,内存使用率就会崩溃,显然是由于垃圾收集


    这种现象并不特定于内联事件。我看到了一种类似的模式,就是重复分配一个大数组,然后覆盖对该大数组的引用,为GC留下大量孤立的内存。内存增加了一段时间,然后GC开始工作。

    Hmm,这很可能是这个问题的最佳答案。我确实注意到它最终会被垃圾收集,但我想知道是否有一种方法可以显式地处理它。我注意到很多数组在内存周围浮动,特别是在使用主干并将视图保存到数组中以供参考时。通常,没有办法显式地触发GC。(请参阅。)如果您在文本输入中反复输入文本,您最终会看到GC启动和内存使用崩溃吗?这就是我在大约5或6个条目后看到的。如果您看到相同的情况,我会将这归因于GC反应有点慢,并让您注意更多真实泄漏的证据。是的,显式连接侦听器将定义它ely允许稍后解除绑定,但我更关注边缘情况。