JavaScript에서 부모 요소 만 제거하고 자식 요소는 제거하지 않는 방법?


89

의 말을하자:

<div>
  pre text
  <div class="remove-just-this">
    <p>child foo</p>
    <p>child bar</p>
    nested text
  </div>
  post text
</div>

이에:

<div>
  pre text
  <p>child foo</p>
  <p>child bar</p>
  nested text
  post text
</div>

Mootools, jQuery 및 심지어 (raw) JavaScript를 사용하는 방법을 알아 냈지만이를 수행하는 방법에 대한 아이디어를 얻지 못했습니다.

답변:


139

jQuery 를 사용하면 다음과 같이 할 수 있습니다.

var cnt = $(".remove-just-this").contents();
$(".remove-just-this").replaceWith(cnt);

문서에 대한 빠른 링크 :

  • 내용 () : jQuery
  • replaceWith ( 내용 : [ 문자열 | 요소 | jQuery ]) : jQuery

위시 나는 (.. 잘못을 실현 발견 )이 2 시간 전 ... 간단하고 우아한 - 멋진!
Tathagata 2011 년

3
'cnt'의 의미는 무엇입니까?
Steven Lu

1
'탄소 나노 튜브'는 "내용"보유 다만 변수 이름입니다
조지 앤더슨

1
왜 그런지 모르겠지만 contents ()를 사용할 때 작동하지 않았습니다. 하지만 contents () 대신 html ()을 사용하면 매력적으로 작동했습니다!
현기증

단 한 줄 버전 :$('.remove-just-this').replaceWith(function() { return $(this).html(); });
Taufik Nur Rahmanda

36

라이브러리 독립적 인 방법은 제거하기 전에 제거 할 요소의 모든 자식 노드를 삽입하는 것입니다 (이전 위치에서 암시 적으로 제거됨).

while (nodeToBeRemoved.firstChild)
{
    nodeToBeRemoved.parentNode.insertBefore(nodeToBeRemoved.firstChild,
                                            nodeToBeRemoved);
}

nodeToBeRemoved.parentNode.removeChild(nodeToBeRemoved);

그러면 모든 자식 노드가 올바른 순서로 올바른 위치로 이동합니다.


3
현대 JS이 지원 :node.replaceWith(...node.childNodes);
Gibolt

34

당신은 아닌 DOM이 작업을 수행 할 수 있는지 확인해야한다 innerHTML(그리고 JK가 제공하는 jQuery를 솔루션을 사용하는 경우, 반드시 오히려 사용하여보다 DOM 노드를 이동하는 것을 확인 innerHTML이벤트 핸들러 등을 보존하기 위해 내부적으로).

내 대답은 insin과 매우 비슷하지만 큰 구조에서 더 잘 수행됩니다 (각 노드를 개별적으로 추가하면 CSS가 각각에 대해 다시 적용되어야하는 다시 그리기에 부담이 될 수 있습니다 appendChild.을 사용하면 DocumentFragment이 작업이 끝날 때까지 표시되지 않으므로 한 번만 발생합니다. 하위 항목이 모두 추가되고 문서에 추가됨).

var fragment = document.createDocumentFragment();
while(element.firstChild) {
    fragment.appendChild(element.firstChild);
}
element.parentNode.replaceChild(fragment, element);

감사합니다; 짧고 직접적인.
brunoais



7

현대 JS를 사용하십시오!

const node = document.getElementsByClassName('.remove-just-this')[0];
node.replaceWith(...node.childNodes); // or node.children, if you don't want textNodes

oldNode.replaceWith(newNode) 유효한 ES5

...array 각 배열 요소를 매개 변수로 전달하는 확산 연산자입니다.


2

어떤 라이브러리를 사용하든 DOM에서 외부 div를 제거하기 전에 내부 div를 복제해야합니다. 그런 다음 복제 된 내부 div를 외부 div가 있던 DOM의 위치에 추가해야합니다. 따라서 단계는 다음과 같습니다.

  1. 외부 div의 부모에 대한 참조를 변수에 저장
  2. 내부 div를 다른 변수에 복사합니다. innerHTML내부 div를 변수 에 저장하여 빠르고 더러운 방식으로 수행 하거나 내부 트리를 노드별로 재귀 적으로 복사 할 수 있습니다.
  3. 전화 removeChild인수로 외부 사업부와 외부 DIV의 부모에.
  4. 복사 한 내부 콘텐츠를 올바른 위치에있는 외부 div의 부모에 삽입합니다.

일부 라이브러리는이 작업의 일부 또는 전부를 수행하지만 위와 같은 작업이 내부적으로 진행됩니다.



1

div를 해당 내용으로 바꿉니다.

const wrapper = document.querySelector('.remove-just-this');
wrapper.outerHTML = wrapper.innerHTML;
<div>
  pre text
  <div class="remove-just-this">
    <p>child foo</p>
    <p>child bar</p>
    nested text
  </div>
  post text
</div>


0

잠옷에서 이와 동일한 작업을 수행하려면 다음과 같이하십시오. 그것은 훌륭하게 작동합니다 (눈꺼풀에 감사드립니다). 덕분에 엉망이되지 않고 스타일을 제대로 수행하는 적절한 서식있는 텍스트 편집기를 만들 수있었습니다.

def remove_node(doc, element):
    """ removes a specific node, adding its children in its place
    """
    fragment = doc.createDocumentFragment()
    while element.firstChild:
        fragment.appendChild(element.firstChild)

    parent = element.parentNode
    parent.insertBefore(fragment, element)
    parent.removeChild(element)

1
이것은 어떤 언어입니까?
brunoais

사용자가 언급 한 이후로 의미가있는 파이썬처럼 보입니다 pyjamas.
mgilson

0

중요한 DOM에서 작업하는 동안 성능 측면 에서 최상의 답변을 찾고있었습니다 .

눈꺼풀 없음의 대답은 자바 스크립트를 사용하면 성능이 가장 좋을 것이라고 지적했습니다.

제거 할 섹션 내부에 복잡한 DOM 구성을 사용하여 5,000 줄과 400,000 자에 대해 다음 실행 시간 테스트를 수행했습니다. 자바 스크립트를 사용할 때 편리한 이유로 클래스 대신 ID를 사용하고 있습니다.

$ .unwrap () 사용

$('#remove-just-this').contents().unwrap();

201.237ms

$ .replaceWith () 사용

var cnt = $("#remove-just-this").contents();
$("#remove-just-this").replaceWith(cnt);

156.983ms

자바 스크립트에서 DocumentFragment 사용

var element = document.getElementById('remove-just-this');
var fragment = document.createDocumentFragment();
while(element.firstChild) {
    fragment.appendChild(element.firstChild);
}
element.parentNode.replaceChild(fragment, element);

147.211ms

결론

성능면에서 상대적으로 큰 DOM 구조에서도 jQuery와 자바 스크립트 사용의 차이는 크지 않습니다. 놀랍게도 $.unwrap()에 비해 가장 비용이 많이 드는입니다 $.replaceWith(). 테스트는 jQuery 1.12.4로 수행되었습니다.


0

내 사용 사례에서와 같이 여러 행을 처리하는 경우 다음 줄을 따라 무언가를 사용하는 것이 좋습니다.

 $(".card_row").each(function(){
        var cnt = $(this).contents();
        $(this).replaceWith(cnt);
    });
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.