动态取消绑定eventListeners(垃圾收集)

Dynamically unbind eventListeners (garbage collection)

本文关键字:取消 绑定 eventListeners 动态      更新时间:2023-12-04

我有以下绑定eventListeners的代码:

// this code is part of a larger object
_boundEventsTracker: [],
_$bindEvents: function(){
    var self = this;
    this.actions.forEach(function(acs){
        acs = acs.split(' ');
        var find = document.querySelector(acs[1]);
        if(find!=null){
            // make sure we only bind events once
            if(self._boundEventsTracker.indexOf(acs[1]) == -1){
                find.addEventListener(acs[0], function(e){
                    self.functions[acs[2]].call(self, e);
                });
                self._boundEventsTracker.push(acs[1]);
            }
        } else {
            /* could not bind
            this is usually because the element resides on a partial page */
        }
    });
    console.log("Events:");
    console.log(this._boundEventsTracker.length);
},

this.actions可能看起来像这样,例如:

actions: [
    'click .settings toggleSidebar',
],

在hashchange上,我动态加载一个页面,然后调用_$bindEvents方法(_$loadXMLHttpRequest的基于承诺的包装器):

window.addEventListener('hashchange', function(e){
    self._$load(e).then(function(content){
         document.querySelector('.pageArea').innerHTML=content; // <- populate here
         self._$bindEvents();
    }});

这带来了以下优势:每当hashbang发生变化时,就会加载一个新视图,将html轮询到主视图中,然后将事件绑定到该特定部分视图中的元素。

1当视图稍后被销毁(清理)时,是否有必要取消绑定eventListeners

2将许多eventListener加载到内存中是否存在性能问题

  1. no,垃圾收集器将删除已从DOM中删除的节点的事件侦听器。一些旧版本的IE有内存泄漏,但这应该不再是一个问题。

  2. 可能,但可能不是。这取决于您有多少监听器、DOM结构的复杂性、事件委托等。对于这个问题,不可能给出一个通用的答案。如果有,这些问题将在UI中引起注意,而不是在内存消耗中。

如果您正在开发SPA,请考虑将事件委派到顶部,因为与在每个hashchange上绑定/重新绑定所有事件相比,它们将变得更易于管理。

此外,使用这样的自定义事件抽象可能是未来同事或合作者需要理解的问题。