Jeśli mam element nadrzędny z elementami podrzędnymi, do których są przypisane nasłuchiwania zdarzeń, czy muszę je usunąć, zanim wyczyszczę element nadrzędny? (tj. parent.innerHTML = '';
) Czy mogą wystąpić przecieki pamięci, jeśli nasłuchiwanie zdarzeń nie jest niezwiązane z elementem, jeśli został usunięty z modelu DOM?
javascript
dom
memory-leaks
dom-events
Wszyscy pracownicy są niezbędni
źródło
źródło
IE < 10
można to bezpiecznie uznać za przestarzałe i nieużywane przez nikogo, kto odwiedza witryny inne niż Yahoo i AOL w tym momencie. Każdy, kto w tym momencie w sposób unikatowy używa IE, prawdopodobnie padnie ofiarą oszustwa telefonicznego w Indiach lub dostanie wirusa, niż ma problemy z obsługą zdarzeń spowalniającą przeglądarkę.Po prostu zaktualizuj informacje tutaj. Testowałem różne przeglądarki, szczególnie pod kątem wycieków pamięci dla cyklicznie zależnych detektorów zdarzeń w zdarzeniach onload iframe.
Użyty kod (jsfiddle przeszkadza w testowaniu pamięci, więc użyj własnego serwera, aby to przetestować):
<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>
Jeśli nie ma wycieku pamięci, po wykonaniu testów używana pamięć wzrośnie o około 1000 KB lub mniej. Jeśli jednak nastąpi wyciek pamięci, pamięć zwiększy się o około 16 000 KB. Usunięcie detektora zdarzeń w pierwszej kolejności zawsze powoduje mniejsze zużycie pamięci (brak wycieków).
Wyniki:
Wniosek: aplikacje z najnowszymi rozwiązaniami mogą prawdopodobnie uniknąć usuwania detektorów zdarzeń. Ale mimo irytacji nadal uważam to za dobrą praktykę.
źródło