Есть ли способ интроспекции узла dom, чтобы увидеть, есть ли обработчики событий, поэтому вы можете эффективно записывать безопасную функцию для удаления узлов dom, не беспокоясь о утечке памяти влево обработчиками событий? Я надеялся сделать это в общем виде.Автоматический обработчик событий удаляется при очистке дочерних узлов dom
ответ
Из того, что я вижу, это не может быть возможно, вот цитата из 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/
Это зависит от многого. Простые обработчики событий, присваиваемые свойством вроде 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
функциональность в своей собственной функции, и удалить их, когда элемент должен быть удален.
У меня было это подозрительное подозрение, что не удалось добраться до списка подключенных обработчиков от использования Firebug и посмотреть на свойства на узлах DOM. Подход атрибутов является хорошим, если страница была закодирована таким образом, купите, я склонен следовать за советом Ника Закаса об этом и избегать использования обработчиков событий с атрибутами. – JGFMK
Не поймите меня неправильно. Я никогда не предлагал использовать атрибуты в качестве обработчиков событий. Фактически последнее предложение является сущностью моего ответа. ** Если ** вы контролируете все события на странице, вы можете очень легко переносить обработку событий **, поэтому удаление обработчиков событий с данного узла не должно быть проблемой. Обертыванием я имею в виду что-то вроде: http://dean.edwards.name/weblog/2005/10/add-event/, я думаю, что мой ответ в значительной степени соответствует тому, что здесь задают. – galambalazs
Cheers. Ссылка на YDN внизу дала больше смысла. Я предполагаю, что вы должны использовать YUI namespaced addEventListener, и я предполагаю, что это отслеживает слушателей, увеличивая узлы с помощью коллекции слушателей. – JGFMK