Si j'ai un élément parent avec des enfants qui ont des écouteurs d'événements liés, dois-je supprimer ces écouteurs d'événements avant de supprimer le parent? (c'est à dire., parent.innerHTML = '';
) Pourrait-il y avoir des fuites de mémoire si les écouteurs d'événements ne sont pas dissociés d'un élément s'il est supprimé du DOM?
Réponse courte: oui
Réponse longue: la plupart des navigateurs gèrent cela correctement et suppriment ces gestionnaires eux-mêmes. Il existe des navigateurs plus anciens (IE 6 et 7, si je me souviens bien) qui gâchent cela. Oui, il pourrait y avoir des fuites de mémoire. Vous ne devriez pas avoir à vous en préoccuper, mais vous devez le faire. Jetez un oeil à ce document .
Juste pour mettre à jour les informations ici. J'ai testé divers navigateurs, en particulier pour les fuites de mémoire pour les écouteurs d'événements dépendants de manière circulaire sur les événements de chargement iframe.
Le code utilisé (jsfiddle interfère avec les tests de mémoire, alors utilisez votre propre serveur pour le tester):
<div>
<label>
<input id="eventListenerCheckbox" type="checkbox" /> Clear event listener when removing iframe
</label>
<div>
<button id="startTestButton">Start Test</button>
</div>
</div>
<div>
<pre id="console"></pre>
</div>
<script>
(function() {
var consoleElement = document.getElementById('console');
window.log = function(text) {
consoleElement.innerHTML = consoleElement.innerHTML + '<br>' + text;
};
}());
(function() {
function attachEvent(element, eventName, callback) {
if (element.attachEvent)
{
element.attachEvent(eventName, callback);
}
else
{
element[eventName] = callback;
}
}
function detachEvent(element, eventName, callback) {
if (element.detachEvent)
{
element.detachEvent(eventName, callback);
}
else
{
element[eventName] = null;
}
}
var eventListenerCheckbox = document.getElementById('eventListenerCheckbox');
var startTestButton = document.getElementById('startTestButton');
var iframe;
var generatedOnLoadEvent;
function createOnLoadFunction(iframe) {
var obj = {
increment: 0,
hugeMemory: new Array(100000).join('0') + (new Date().getTime()),
circularReference: iframe
};
return function() {
// window.log('iframe onload called');
obj.increment += 1;
destroy();
};
}
function create() {
// window.log('create called');
iframe = document.createElement('iframe');
generatedOnLoadEvent = createOnLoadFunction(iframe);
attachEvent(iframe, 'onload', generatedOnLoadEvent);
document.body.appendChild(iframe);
}
function destroy() {
// window.log('destroy called');
if (eventListenerCheckbox.checked)
{
detachEvent(iframe, 'onload', generatedOnLoadEvent)
}
document.body.removeChild(iframe);
iframe = null;
generatedOnLoadEvent = null;
}
function startTest() {
var interval = setInterval(function() {
create();
}, 100);
setTimeout(function() {
clearInterval(interval);
window.log('test complete');
}, 10000);
}
attachEvent(startTestButton, 'onclick', startTest);
}());
</script>
S'il n'y a pas de fuite de mémoire, la mémoire utilisée augmentera d'environ 1000 Ko ou moins après l'exécution des tests. Cependant, s'il y a une fuite de mémoire, la mémoire augmentera d'environ 16 000 Ko. La suppression de l'écouteur d'événements entraîne d'abord une utilisation moindre de la mémoire (aucune fuite).
Résultats:
Conclusion: les applications Bleeding Edge peuvent probablement éviter de supprimer les écouteurs d'événements. Mais je considérerais quand même que c'est une bonne pratique, malgré l'ennui.