0

Есть ли способ интроспекции узла dom, чтобы увидеть, есть ли обработчики событий, поэтому вы можете эффективно записывать безопасную функцию для удаления узлов dom, не беспокоясь о утечке памяти влево обработчиками событий? Я надеялся сделать это в общем виде.Автоматический обработчик событий удаляется при очистке дочерних узлов dom

ответ

0

Из того, что я вижу, это не может быть возможно, вот цитата из MOZILLA сайта:

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

памяти вопросы

document.addEventListener ("нагрузка", функцию (событие) {obj.func (событие);}, false);

Вызов addEventListener для анонимной функции создает новый прослушиватель каждый раз. Вызов removeEventListener для анонимного Функция не действует. Анонимная функция создает уникальный объект, каждый из которых вызывается , это не ссылка на существующий объект, хотя он может назвать один. При добавлении события слушателем таким образом обязательно, чтобы он был добавлен только один раз, он постоянный (может быть удален ) до уничтожения объекта, который был добавлен .

Если слушатель не является анонимным, вы можете это сделать. Вот кусок кода из библиотеки YUI Event:

 /** 
     * 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/

+0

Cheers. Ссылка на YDN внизу дала больше смысла. Я предполагаю, что вы должны использовать YUI namespaced addEventListener, и я предполагаю, что это отслеживает слушателей, увеличивая узлы с помощью коллекции слушателей. – JGFMK

0

Это зависит от многого. Простые обработчики событий, присваиваемые свойством вроде el.onclick = ..., могут быть эффективно удалены, но список обработчиков, добавленных через attachEvent(), отсутствует в IE. 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 функциональность в своей собственной функции, и удалить их, когда элемент должен быть удален.

+0

У меня было это подозрительное подозрение, что не удалось добраться до списка подключенных обработчиков от использования Firebug и посмотреть на свойства на узлах DOM. Подход атрибутов является хорошим, если страница была закодирована таким образом, купите, я склонен следовать за советом Ника Закаса об этом и избегать использования обработчиков событий с атрибутами. – JGFMK

+0

Не поймите меня неправильно. Я никогда не предлагал использовать атрибуты в качестве обработчиков событий. Фактически последнее предложение является сущностью моего ответа. ** Если ** вы контролируете все события на странице, вы можете очень легко переносить обработку событий **, поэтому удаление обработчиков событий с данного узла не должно быть проблемой. Обертыванием я имею в виду что-то вроде: http://dean.edwards.name/weblog/2005/10/add-event/, я думаю, что мой ответ в значительной степени соответствует тому, что здесь задают. – galambalazs