DOM 엘리먼트를 삭제했을 경우, 그 리스너도 메모리에서 삭제됩니까?
DOM 엘리먼트를 삭제했을 경우, 그 리스너도 메모리에서 삭제됩니까?
최신 브라우저
플레인 자바스크립트
삭제된 DOM 요소가 참조가 없는 경우(참조가 없는 경우), 요소 자체는 가비지 컬렉터 및 관련된 이벤트 핸들러/리슨에 의해 선택됩니다.
var a = document.createElement('div');
var b = document.createElement('p');
// Add event listeners to b etc...
a.appendChild(b);
a.removeChild(b);
b = null;
// A reference to 'b' no longer exists
// Therefore the element and any event listeners attached to it are removed.
단, 여전히 해당 요소를 가리키는 참조가 있는 경우 요소와 해당 이벤트 청취자는 메모리에 유지됩니다.
var a = document.createElement('div');
var b = document.createElement('p');
// Add event listeners to b etc...
a.appendChild(b);
a.removeChild(b);
// A reference to 'b' still exists
// Therefore the element and any associated event listeners are still retained.
j쿼리
(jQuery 등)는.remove()
(를 참조하면) 똑같이 합니다.remove()
있습니다.removeChild()
★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
그러나 이것은 사실이 아닙니다; jQuery 라이브러리는 실제로 (문서화되어 있지 않고 이론적으로 언제든지 변경될 수 있는) 내부 메서드를 가지고 있습니다.cleanData()
(이 메서드는 다음과 같습니다)DOM에서 삭제되면 요소와 관련된 모든 데이터/이벤트가 자동으로 지워집니다(이 메서드는 다음과 같습니다). remove()
,empty()
,html("")
。
오래된 브라우저
오래된 브라우저(특히 오래된 버전의 IE)에서는 이벤트청취자가 연결된 요소에 대한 참조를 유지하기 때문에 메모리 누수 문제가 발생하는 것으로 알려져 있습니다.
레거시 IE 버전의 메모리 누전을 수정하기 위해 사용되는 원인, 패턴 및 솔루션에 대해 자세히 설명하고 싶다면 이 MSDN 기사 "Internet Explorer 누전 패턴의 이해와 해결"을 읽어보실 것을 권장합니다.
이와 관련된 몇 가지 추가 기사:
이 경우 수신기를 직접 제거하는 것이 좋습니다(메모리가 애플리케이션에 매우 중요하고 실제로 이러한 브라우저를 대상으로 하는 경우에만).
jQuery에 대해서:
.remove() 메서드는 요소를 DOM에서 꺼냅니다.요소 자체와 요소 내부의 모든 요소를 삭제할 경우 .remove()를 사용합니다.요소 자체와 더불어 요소와 관련된 모든 바인딩 이벤트 및 jQuery 데이터가 제거됩니다.데이터나 이벤트를 삭제하지 않고 요소를 삭제하려면 대신 .detach()를 사용합니다.
참고 자료: http://api.jquery.com/remove/
jQuery v1.8.2.remove()
소스 코드:
remove: function( selector, keepData ) {
var elem,
i = 0;
for ( ; (elem = this[i]) != null; i++ ) {
if ( !selector || jQuery.filter( selector, [ elem ] ).length ) {
if ( !keepData && elem.nodeType === 1 ) {
jQuery.cleanData( elem.getElementsByTagName("*") );
jQuery.cleanData( [ elem ] );
}
if ( elem.parentNode ) {
elem.parentNode.removeChild( elem );
}
}
}
return this;
}
분명히 jQuery는node.removeChild()
https://developer.mozilla.org/en-US/docs/DOM/Node.removeChild에 따르면,
The removed child node still exists in memory, but is no longer part of the DOM. You may reuse the removed node later in your code, via the oldChild object reference.
즉, 이벤트 리스너는 삭제될 수 있지만,node
아직 메모리에 존재합니다.
이벤트 핸들러의 메모리누설이 닫힌 요소에 대한 참조를 유지하고 있는 이벤트핸들러와 이벤트핸들러에 대한 참조를 유지하는 요소에 대해서는, 주저하지 말아 주세요.
가비지 컬렉터는 순환 참조를 좋아하지 않습니다.
일반적인 메모리 누출 사례: 객체에 요소에 대한 참조가 있음을 인정합니다.그 요소에는 핸들러에 대한 참조가 있습니다.그리고 핸들러는 오브젝트에 대한 참조를 가지고 있습니다.오브젝트에는 많은 다른 오브젝트에 대한 참조가 있습니다.이 오브젝트는 컬렉션에서 참조를 취소하여 폐기했다고 생각되는 컬렉션의 일부입니다.=> 오브젝트 전체와 참조하는 모든 것은 페이지가 종료될 때까지 메모리에 남습니다.=> 오브젝트 클래스의 완전한 킬링 방법을 생각하거나 MVC 프레임워크를 신뢰해야 합니다.
또한 Chrome 개발 도구의 Retaining tree 부분을 사용하는 것도 망설이지 마십시오.
다른 답변들을 연장하는 것 뿐인데...
위임된 이벤트 핸들러는 요소 제거 시 제거되지 않습니다.
$('body').on('click', '#someEl', function (event){
console.log(event);
});
$('#someEL').remove(); // removing the element from DOM
이제 확인:
$._data(document.body, 'events');
에 관하여jQuery
, 다음의 일반적인 메서드는 데이터 핸들러나 이벤트핸들러등의 다른 구성도 삭제합니다.
요소 자체와 더불어 요소와 관련된 모든 바인딩 이벤트 및 jQuery 데이터가 제거됩니다.
메모리 누수를 방지하기 위해 jQuery는 요소 자체를 삭제하기 전에 하위 요소에서 데이터 및 이벤트 핸들러 등의 다른 구성을 제거합니다.
또한 jQuery는 하위 요소에서 데이터 및 이벤트 핸들러와 같은 다른 구성 요소를 제거한 후 해당 요소를 새 컨텐츠로 바꿉니다.
네, 가비지 콜렉터도 그것들을 제거할 것입니다.그러나 레거시 브라우저에서는 항상 해당되지 않을 수 있습니다.
언급URL : https://stackoverflow.com/questions/12528049/if-a-dom-element-is-removed-are-its-listeners-also-removed-from-memory
'it-source' 카테고리의 다른 글
VueJ: Vue에서 계산된 "set/get"을 사용합니다.드래그 가능 및 VueX (0) | 2022.11.19 |
---|---|
인덱스를 사용하지 않고 중복 삽입 방지 (0) | 2022.11.19 |
jQuery를 사용하여 JavaScript 개체에서 선택한 항목에 옵션을 추가하는 가장 좋은 방법은 무엇입니까? (0) | 2022.11.19 |
Vuejs가 mixin에서 속성을 읽지 않음 및 내보내기 NOT FOUND 오류입니다. (0) | 2022.11.19 |
이름이 없는 Java 메서드 호출 (0) | 2022.11.19 |