8

Supposons que j'ai attaché une variété d'écouteurs d'événements à divers éléments de formulaire. Plus tard, je veux supprimer le formulaire entier.Les écouteurs d'événements javascript doivent-ils être supprimés avant de supprimer l'élément auquel ils sont attachés?

Est-il nécessaire (ou suggéré) de désenregistrer les gestionnaires d'événements qui existent sur le formulaire et ses éléments? Si oui, quel est le moyen le plus simple de supprimer tous les écouteurs d'une collection d'éléments? Quelles sont les répercussions de ne pas le faire? J'utilise Prototype, si c'est important.

Voici ce que je suis en train de faire. J'ai une forme simple, comme celui-ci:

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

J'observe divers événements sur les entrées, par exemple:

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

etc.

Le formulaire est transmis via AJAX et la réponse est nouvelle copie du formulaire. Je remplace l'ancien formulaire par une copie du nouveau faisant quelque chose comme $('form').replace(newForm). Suis-je en train d'accumuler un tas d'événements cruels?

Répondre

3

Oui, un peu. Pas assez pour être un énorme problème, mais les anciennes versions d'IE vont fuir dans ces circonstances.

À partir du prototype 1.6.1 (actuellement dans sa version finale candidate), la bibliothèque gère ce nettoyage à la page de déchargement. Lorsque vous utilisez Prototype pour ajouter un observateur d'événement, il conserve une référence à cet élément dans un tableau; à la page de déchargement, il boucle à travers ce tableau et supprime tous vos observateurs. Toutefois, si l'utilisateur reste sur cette page pendant un certain temps, l'utilisation de la mémoire s'accumulera au cours de la vie de la page. Vous avez plusieurs options:

  1. pour des événements sur Écouter un ancêtre de la forme, qui ne sera remplacé. Ensuite, dans votre gestionnaire, vérifiez d'où vient l'événement. (par exemple, "délégation d'événement")

  2. Désactivez explicitement tous vos appels avant d'appeler Element#replace. Dans votre exemple, vous feriez:

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

Cela équivaut à appeler stopObserving sans argument, ce qui a pour effet de supprimer tous les gestionnaires sur un élément donné.

Je recommande l'option 1.

(Nous avons parlé de faire la suppression automatique de l'auditeur dans une future version de prototype dans le cadre de Element#update et Element#replace, mais il est un compromis de performance.)

4

Les événements qui ne sont pas enregistrés peuvent ne pas libérer automatiquement leur mémoire. Ceci est particulièrement un problème dans les anciennes versions de IE.

Prototype utilisé pour avoir un système de collecte automatique des ordures pour cela, mais la méthode a été supprimée dans la version 1.6. Il est documenté here. Si la suppression de la méthode signifie que la collecte des ordures n'a plus lieu, ou que la méthode n'est plus accessible au public, je ne sais pas. Notez également que la page n'a jamais été déchargée, ce qui signifie que si vos utilisateurs restent longtemps sur la même page tout en effectuant de nombreuses mises à jour AJAX et DOM, la mémoire risque de fuir de façon inacceptable même lors de cette visite.

0

Il est toujours bon de supprimer les écouteurs d'événement des éléments supprimés du DOM dans le cas du scénario mentionné ci-dessous par Jonas.

Questions connexes