IT박스

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

itboxs 2020. 9. 13. 10:16
반응형

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


의 말을하자:

<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를 사용하는 방법을 알아 냈지만이 작업을 수행하는 방법을 알 수 없습니다.


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

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

문서에 대한 빠른 링크 :

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

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

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

nodeToBeRemoved.parentNode.removeChild(nodeToBeRemoved);

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


이벤트 핸들러와 같은 것을 보존하기 위해 innerHTMLDOM이 아닌 DOM을 사용 하여이 작업을 수행해야합니다 (jk에서 제공하는 jQuery 솔루션을 사용하는 경우 innerHTML내부적으로 사용하지 않고 DOM 노드를 이동해야 함 ).

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

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

 $('.remove-just-this > *').unwrap()

더 우아한 방법은

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

현대 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 각 배열 요소를 매개 변수로 전달하는 확산 연산자입니다.


Whichever library you are using you have to clone the inner div before removing the outer div from the DOM. Then you have to add the cloned inner div to the place in the DOM where the outer div was. So the steps are:

  1. Save a reference to the outer div's parent in a variable
  2. Copy the inner div to another variable. This can be done in a quick and dirty way by saving the innerHTML of the inner div to a variable or you can copy the inner tree recursively node by node.
  3. Call removeChild on the outer div's parent with the outer div as the argument.
  4. Insert the copied inner content to the outer div's parent in the correct position.

Some libraries will do some or all of this for you but something like the above will be going on under the hood.


And, since you tried in mootools as well, here's the solution in mootools.

var children = $('remove-just-this').getChildren();
children.replaces($('remove-just-this');

Note that's totally untested, but I have worked with mootools before and it should work.

http://mootools.net/docs/Element/Element#Element:getChildren

http://mootools.net/docs/Element/Element#Element:replaces


if you'd like to do this same thing in pyjamas, here's how it's done. it works great (thank you to eyelidness). i've been able to make a proper rich text editor which properly does styles without messing up, thanks to this.

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)

I was looking for the best answer performance-wise while working on an important DOM.

eyelidlessness's answer was pointing out that using javascript the performances would be best.

I've made the following execution time tests on 5,000 lines and 400,000 characters with a complexe DOM composition inside the section to remove. I'm using an ID instead of a class for convenient reason when using javascript.

Using $.unwrap()

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

201.237ms

Using $.replaceWith()

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

156.983ms

Using DocumentFragment in javascript

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

Conclusion

Performance-wise, even on a relatively big DOM structure, the difference between using jQuery and javascript is not huge. Surprisingly $.unwrap() is most costly than $.replaceWith(). The tests have been done with jQuery 1.12.4.


If you are dealing with multiple rows, as it was in my use case you are probably better off with something along these lines:

 $(".card_row").each(function(){
        var cnt = $(this).contents();
        $(this).replaceWith(cnt);
    });

Replace div with its contents:

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>

참고URL : https://stackoverflow.com/questions/170004/how-to-remove-only-the-parent-element-and-not-its-child-elements-in-javascript

반응형