代码之家  ›  专栏  ›  技术社区  ›  JGFMK

清除DOM节点子级时自动删除事件处理程序

  •  0
  • JGFMK  · 技术社区  · 15 年前

    有没有一种方法可以内省一个dom节点以查看是否附加了事件处理程序,这样您就可以有效地编写一个安全函数来清除dom节点,而不必担心事件处理程序留下的内存泄漏?我希望用一种通用的方式来实现这一点。

    2 回复  |  直到 15 年前
        1
  •  0
  •   Roman Goyenko    15 年前

    据我所见,这可能是不可能的,下面是来自Mozilla网站的引言:

    https://developer.mozilla.org/en/DOM/element.addEventListener#Memory_issues

    内存问题

    document.addEventListener(“加载”, 函数(事件)obj.func(事件);, 错误);

    将AddEventListener调用到 匿名函数创建新的 每次都听。打电话 removeEventListener到匿名 函数无效。匿名的 函数创建一个唯一的对象 时间就是时间,它不是 但是,对现有对象的引用 它可以叫一个。添加事件时 以这种方式倾听,确保是 仅添加一次,它是永久的(可以 直到物体 添加到的已销毁。

    如果听众不是匿名的,你可以这样做。以下是Yui图书馆活动的代码:

            /**
             * Returns all listeners attached to the given element via addListener.
             * Optionally, you can specify a specific type of event to return.
             * @method getListeners
             * @param el {HTMLElement|string} the element or element id to inspect 
             * @param sType {string} optional type of listener to return. If
             * left out, all listeners will be returned
             * @return {Object} the listener. Contains the following fields:
             *   type:   (string)   the type of event
             *   fn:     (function) the callback supplied to addListener
             *   obj:    (object)   the custom object supplied to addListener
             *   adjust: (boolean|object)  whether or not to adjust the default context
             *   scope: (boolean)  the derived context based on the adjust parameter
             *   index:  (int)      its position in the Event util listener cache
             * @static
             */           
            getListeners: function(el, sType) {
                var results=[], searchLists;
                if (!sType) {
                    searchLists = [listeners, unloadListeners];
                } else if (sType === "unload") {
                    searchLists = [unloadListeners];
                } else {
                    sType = this._getType(sType);
                    searchLists = [listeners];
                }
    
                var oEl = (YAHOO.lang.isString(el)) ? this.getEl(el) : el;
    
                for (var j=0;j<searchLists.length; j=j+1) {
                    var searchList = searchLists[j];
                    if (searchList) {
                        for (var i=0,len=searchList.length; i<len ; ++i) {
                            var l = searchList[i];
                            if ( l  && l[this.EL] === oEl && 
                                    (!sType || sType === l[this.TYPE]) ) {
                                results.push({
                                    type:   l[this.TYPE],
                                    fn:     l[this.FN],
                                    obj:    l[this.OBJ],
                                    adjust: l[this.OVERRIDE],
                                    scope:  l[this.ADJ_SCOPE],
                                    index:  i
                                });
                            }
                        }
                    }
                }
    
                return (results.length) ? results : null;
            },
    

    您可以在此处阅读更多信息: http://developer.yahoo.com/yui/event/

        2
  •  0
  •   gblazex    15 年前

    视情况而定。由类似这样的属性分配的简单事件处理程序 el.onclick = ... 可以有效地删除,但没有通过 attachEvent() 在里面 工业工程 . Memory leaks 在其他浏览器中不太重要。

    /**
    * The purge function takes a reference to a DOM element as an argument. 
    * It loops through the element's attributes. If it finds any functions, 
    * it nulls them out. This breaks the cycle, allowing memory to be reclaimed. 
    * It will also look at all of the element's descendent elements, and clear 
    * out all of their cycles as well.
    *  - http://javascript.crockford.com/memory/leak.html
    */
    function purge(d) {
        var a = d.attributes, i, l, n;
        if (a) {
            l = a.length;
            for (i = 0; i < l; i += 1) {
                n = a[i].name;
                if (typeof d[n] === 'function') {
                    d[n] = null;
                }
            }
        }
        a = d.childNodes;
        if (a) {
            l = a.length;
            for (i = 0; i < l; i += 1) {
                purge(d.childNodes[i]);
            }
        }
    }
    

    如果要处理这两种情况并管理页面中的所有事件处理程序,则可以 addEvent 在您自己的函数中的函数,并在要删除元素时删除它们。