자바 스크립트 DOM 제거 요소


198

DOM 요소가 존재하는지 테스트하고 존재하는 경우 삭제하고 존재하지 않는 경우 작성하십시오.

var duskdawnkey = localStorage["duskdawnkey"];
var iframe = document.createElement("iframe");
var whereto = document.getElementById("debug");
var frameid = document.getElementById("injected_frame");
iframe.setAttribute("id", "injected_frame");
iframe.setAttribute("src", 'http://google.com');
iframe.setAttribute("width", "100%");
iframe.setAttribute("height", "400");

if (frameid) // check and see if iframe is already on page
{ //yes? Remove iframe
    iframe.removeChild(frameid.childNodes[0]);
} else // no? Inject iframe
{
    whereto.appendChild(iframe);
    // add the newly created element and it's content into the DOM
    my_div = document.getElementById("debug");
    document.body.insertBefore(iframe, my_div);
}

요소가 있는지 확인하고 요소를 만드는 것은 작동하지만 요소를 삭제해도 효과가 없습니다. 기본적 으로이 코드는 버튼을 클릭하여 iframe을 웹 페이지에 삽입합니다. 내가하고 싶은 것은 iframe이 이미 삭제되어 있는지입니다. 그러나 어떤 이유로 든 실패합니다.


답변:


338

removeChild 부모에 대해 호출해야합니다. 예 :

parent.removeChild(child);

귀하의 예에서 다음과 같은 작업을 수행해야합니다.

if (frameid) {
    frameid.parentNode.removeChild(frameid);
}

고맙습니다 내가 당신의 게시물을 읽기 직전에 알아 냈습니다. whereto.removeChild (whereto.childNodes [0]);로 변경해야합니다.
Joshua Redfield

6
프레임이 항상 debugdiv 의 첫 번째 자식이라고 가정하면 작동합니다 . 사용 parentNode은 모든 요소에서 작동하는보다 일반적인 솔루션입니다.
casablanca

1
이 솔루션으로는 충분하지 않을 수 있습니다. 이 글을 읽는 사람이라면 Glenn의 제안을 살펴보십시오
Sebas

79

대부분의 브라우저에는 .removeChild(element)부모를 호출 하는 것보다 DOM에서 요소를 제거하는 약간 더 간결한 방법이 element.remove()있습니다. 물론 이것은 DOM에서 요소를 제거하는 표준적이고 관용적 인 방법이 될 것입니다.

.remove()방법은 2011 년 DOM Living Standard에 추가되었습니다 ( 커밋 )에 추가되었으며 이후 Chrome, Firefox, Safari, Opera 및 Edge에서 구현되었습니다. 모든 버전의 Internet Explorer에서는 지원되지 않습니다.

오래된 브라우저를 지원하려면 브라우저를 연결해야합니다. 이 메소드를 포함하는 다목적 DOM shim을 만든 사람이없고 단일 프로토 타입에 메소드를 추가하는 것이 아니기 때문에 약간 짜증나는 것으로 밝혀졌습니다. 이 메소드 ChildNode는 스펙에 의해 정의 된 인터페이스 일 뿐이며 JavaScript에 액세스 할 수 없으므로 프로토 타입에 아무것도 추가 할 수 없습니다. 따라서 ChildNode브라우저에서 상속되고 실제로 정의 된 모든 프로토 타입을 찾아서 추가 .remove해야합니다.

IE 8에서 작동하는 것으로 확인한 shim이 있습니다.

(function () {
    var typesToPatch = ['DocumentType', 'Element', 'CharacterData'],
        remove = function () {
            // The check here seems pointless, since we're not adding this
            // method to the prototypes of any any elements that CAN be the
            // root of the DOM. However, it's required by spec (see point 1 of
            // https://dom.spec.whatwg.org/#dom-childnode-remove) and would
            // theoretically make a difference if somebody .apply()ed this
            // method to the DOM's root node, so let's roll with it.
            if (this.parentNode != null) {
                this.parentNode.removeChild(this);
            }
        };

    for (var i=0; i<typesToPatch.length; i++) {
        var type = typesToPatch[i];
        if (window[type] && !window[type].prototype.remove) {
            window[type].prototype.remove = remove;
        }
    }
})();

IE 7 이하에서는 작동하지 않습니다. IE 8 이전에는 DOM 프로토 타입을 확장 하지 않습니다 . 그러나 2015 년 직전에 대부분의 사람들은 그런 것들에 신경 쓸 필요가 없다고 생각합니다.

shim을 포함하면 element간단히 호출하여 DOM에서 DOM 요소를 제거 할 수 있습니다.

element.remove();

1
그냥이 여기 떠나 : polyfill.io/v2/docs/features/#Element_prototype_remove는 당신이 자동으로 자료의 polyfill 서비스를 포함하는 경우 당신이 IE 7에 지원 다시 얻을 것이다
complistic

4
IE에 신경 쓰지 않는 한 2017 년에 그렇게하는 방법입니다. 참조 : developer.mozilla.org/en-US/docs/Web/API/ChildNode/remove
nevf

45

의견을 게시 할 담당자가 충분하지 않은 것 같으므로 다른 답변을해야합니다.

removeChild ()를 사용하거나 부모에서 innerHTML 속성을 설정하여 노드를 연결 해제 할 때이를 참조하는 다른 항목이 없는지 확인해야합니다. 그렇지 않으면 실제로 손상되지 않으며 메모리 누수가 발생합니다. removeChild ()를 호출하기 전에 노드에 대한 참조를 취할 수있는 많은 방법이 있으며 범위를 벗어나지 않은 참조는 명시 적으로 제거해야합니다.

더그 크록 포드의 글을 여기에 () 이벤트 핸들러가 IE에서 순환 참조의 원인이 알려져 있으며에서 removeChild를 호출하기 전에 명시 적으로 그들을 제거 다음 제안 있음

function purge(d) {
    var a = d.attributes, i, l, n;
    if (a) {
        for (i = a.length - 1; i >= 0; i -= 1) {
            n = a[i].name;
            if (typeof d[n] === 'function') {
                d[n] = null;
            }
        }
    }
    a = d.childNodes;
    if (a) {
        l = a.length;
        for (i = 0; i < l; i += 1) {
            purge(d.childNodes[i]);
        }
    }
}

그리고 많은 예방 조치를 취하더라도 Jens-Ingo Farley의 설명대로 IE에서 여전히 메모리 누수가 발생할 수 있습니다. .

마지막으로 자바 스크립트 삭제 가 답 이라고 생각하는 함정에 빠지지 마십시오 . 많은 사람들이 제안한 것처럼 보이지만 일을하지는 않습니다. Kangax의 삭제 이해에 대한 훌륭한 참고 자료는 다음과 같습니다 .


1
아마도 이것을 증명하기 위해 jsFiddle을 보여줄 수 있습니다. 감사합니다
Muhaimin

1
이 동작을 확인합니다. 내 프레임 워크는 dom 레이아웃에서 Javascript 객체 매핑 트리를 사용합니다. 각 js 객체는 해당 dom 요소를 참조합니다. element.parentNode.removeChild요소를 제거하기 위해 전화 를 걸어도 요소는 그대로 유지되며 계속 참조 할 수 있습니다. 일반 돔 트리에서는 보이지 않습니다.
Sebas

예, 그런 다음 js 매핑 객체에 대한 전역 포인터를 제거하면 가비지 수집기의 마법이 해제됩니다. 이것은 허용되는 답변에 중요한 추가 사항입니다.
Sebas

11

사용 ) (Node.removeChild를 당신이 단순히이 같은 것을 사용하기위한 작업을 수행합니다

var leftSection = document.getElementById('left-section');
leftSection.parentNode.removeChild(leftSection);

DOM 4에서는 remove 메소드가 적용되었지만 W3C에 따라 브라우저 지원이 불량합니다.

node.remove () 메소드는 DOM 4 스펙에서 구현됩니다. 그러나 브라우저 지원이 좋지 않기 때문에 사용해서는 안됩니다.

그러나 jQuery를 사용하는 경우 remove 메소드를 사용할 수 있습니다 ...

$('#left-section').remove(); //using remove method in jQuery

또한 새로운 프레임 워크에서 조건을 사용하여 요소를 제거 할 수 있습니다 (예 *ngIf: Angular 및 React에서 다른 뷰를 렌더링하는 경우 조건에 따라 다름).


createElement를 사용하여 js에서 모달 노드를 작성하는 경우 노드를 제거하기 전에 노드가 존재하는지 확인하십시오. if (leftSection) {..your code}가해 야합니다.
Afsan Abdulali Gujarati 23시 55 분

0

화려한 기능을 사용하고 싶다면 :

$("#foo").remove();

DOM에서 요소를 완전히 삭제합니다.

데이터와 이벤트를 제거하지 않고 요소를 제거하려면 다음을 대신 사용하십시오.

$("#foo").detach();

jQuery 문서

.remove()메소드는 DOM에서 요소를 가져옵니다. .remove()요소 자체와 내부의 모든 요소를 ​​제거하려는 경우에 사용하십시오 . 요소 자체 외에도 요소와 관련된 모든 바인딩 된 이벤트 및 jQuery 데이터가 제거됩니다. 데이터와 이벤트를 제거하지 않고 요소를 제거하려면 .detach()대신 사용하십시오.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.