2013-03-20 2 views
2

У меня есть объект, который генерирует элементы HTML, которые также связаны с массивом объекта, и, скажем, у нас есть один экземпляр этого объекта. Так как он создает элементы, он также назначает следующий прослушиватель событий вложенной части элемента (класс - uploadDelete).removeEventListener с уникальной анонимной функцией

Теперь слушателю этого события необходимо вызвать метод удаления экземпляра объекта, который его создал, со значением i, присвоенным при его создании. Поскольку события находятся под окном, экземпляр необходимо передать анонимной функции вместе с значением i.

Это поэтому присваивает уникальную функцию событию, и поскольку метод delete будет уничтожать элемент, содержащий слушателя, я хотел бы сначала удалить его; из того, что я прочитал, это может привести к утечкам в противном случае (?). Я также использую Strict Mode, поэтому не arguments.callee.

file.display.getElementsByClassName('uploadDelete')[0].addEventListener('click', 
(function(that,i){ 
    return function() { 
     that.delete(i); 
    }; 
})(this,i), false); 

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


Вот что я в итоге сделал с помощью ответа Нургуарда. Поскольку уникальность была вытекающей из объекта под названием файла, я просто создал новое свойство файла для хранения функции:

file.deleteFunction = (function(that,i){ 
    return function() { 
     that.delete(i); 
    }; 
})(this,i); 

file.display.getElementsByClassName('uploadDelete')[0].addEventListener('click',file.deleteFunction, false); 

функции удаления, которая вызывается затем удаляет прослушиватель событий.

ответ

2

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

// trivial example 
var listeners = {}, 
    i = 0, 


add = function (context, func, closure) { 
    var enclosed = (function (closure) { 
     return function() { /* ... */; func(); }; 
    }(closure)), 
    index = i; 

    context.addEventListener("...", enclosed, false); 
    listeners[index] = enclosed; 
    i += 1; 
    return index; 
}; 

add теперь добавить слушателя, но и сохранить функцию, которую вы передаете в addEventListener в listeners объекта. Если вам нужна ссылка на i, вы уже получили ее в закрытии, если хотите.

Итак, теперь, когда вы удаляете материал, вы можете просто искать функцию, сохраненную в listeners[i].

Альтернативный вариант, если вы не хотите сохранять таблицу, полную этих в одном месте, по какой-либо причине должна была бы поймать оператор return, а вместо возврата i вернуть функцию;

// inside of your module 
// I'm not usually crazy about `this`, without doing something particular with it, 
// but hopefully it illustrates my point 
this.cached_func = add(this.el, this.callback.bind(this), this.secret); 

Так что теперь, когда приходит время, чтобы удалить все, и вы хотите, чтобы закрыть ваш слушатель ...

remove(this.cached_func); 

Все, что сказал, утечки, которые вы прочитали, о которых все же возможно, но главным виновником был IE6/7 (и ранее).
По мере того, как люди ведут дальше от плохих браузеров, это становится менее важным.
На самом деле поощрение памяти-дампов в IE6, вероятно, просто хороший способ побудить людей не использовать IE6.

+0

Это было похоже на то, о чем я начинал думать. Спасибо за ответ и за это! –

Смежные вопросы