Pergunta

Suponha Anexei uma variedade de ouvintes de eventos para vários elementos de formulário. Mais tarde, eu quero remover o formulário inteiro.

É necessário (ou sugerido) para cancelar o registro quaisquer manipuladores de eventos que existem no formulário e seus elementos? Se assim for, qual é a maneira mais fácil de remover todos os ouvintes em uma coleção de elementos? Quais são as repercussões de não fazê-lo? Estou usando Prototype, se isso importa.

Aqui está o que eu estou realmente fazendo. Eu tenho um formulário simples, como este:

<form id="form">
  <input type="text" id="foo"/>
  <input type="text" id="bar"/>
</form>

Eu observo vários eventos nas entradas, por exemplo:.

$('foo').observe('keypress', onFooKeypress);
$('bar').observe('keypress', onBarKeypress);

etc.

O formulário é enviado via AJAX ea resposta é uma nova cópia do formulário. I substituir a velha forma com uma cópia do novo fazendo algo como $('form').replace(newForm). Am I acumulando um monte de cruft evento?

Foi útil?

Solução

Sim, um pouco. Não o suficiente para ser um problema enorme, mas versões mais antigas do IE vai vazar sob aquelas circunstâncias.

A partir de Prototype 1.6.1 (atualmente em sua versão candidata final), as alças de biblioteca esta limpeza na página de descarregamento. Quando você usar Prototype para adicionar um observador evento, ele mantém uma referência a esse elemento em uma matriz; na página de descarregamento, ele percorre essa matriz e remove todos os seus observadores.

No entanto, se o usuário está indo para permanecer nesta página por um tempo, o uso de memória irá acumular ao longo da vida da página. Você tem várias opções:

  1. Ouça os eventos em um ancestral do formulário, que nunca é substituído. Então, no seu manipulador, verifique onde o evento veio. (Ou seja, "a delegação de evento")

  2. explicitamente cancelar o registro todas as suas chamadas antes de chamar Element#replace. No seu exemplo, você faria:

    $('foo', 'bar').each(Element.stopObserving);
    

Esta é equivalente a chamar stopObserving sem argumentos, que tem o efeito de remover todas manipuladores sobre um determinado elemento.

Eu recomendaria a opção 1.

(Nós conversamos sobre fazer a remoção ouvinte automática em uma versão futura do Prototype, como parte de Element#update e Element#replace, mas é um desempenho trade-off).

Outras dicas

Eventos que não são não registrado não pode libertar a sua memória automaticamente. Isto é especialmente um problema nas versões mais antigas do IE.

Prototype costumava ter um sistema de coleta de lixo automática para isso, mas o método foi removido na versão 1.6. Ele está documentado aqui . Se a remoção dos meios do método que a coleta de lixo não ocorre, ou o método só não é mais disponível publicamente, eu não sei. Também nota que foi sempre apenas chamado na página de descarregamento, o que significa que se os usuários ficar na mesma página por um longo tempo, enquanto fazendo um monte de atualizações Ajax e DOM, a memória pode vazar para níveis inaceitáveis, mesmo durante essa página uma visita.

É sempre bom para remover todos os ouvintes de eventos a partir de elementos que são removidos a partir do DOM no caso do cenário que Jonas mencionados abaixo.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top