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);
이렇게하면 모든 자식 노드가 올바른 순서로 올바른 위치로 이동합니다.
이벤트 핸들러와 같은 것을 보존하기 위해 innerHTML
DOM이 아닌 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:
- Save a reference to the outer div's parent in a variable
- 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. - Call
removeChild
on the outer div's parent with the outer div as the argument. - 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>
'IT박스' 카테고리의 다른 글
소형 장치의 Twitter 부트 스트랩 숨기기 요소 (0) | 2020.09.13 |
---|---|
파이썬 numpy 기계 엡실론 (0) | 2020.09.13 |
bash로 디렉토리가 마운트되었는지 확인하십시오. (0) | 2020.09.13 |
SecurityException : 권한이 거부되었습니다 (인터넷 권한이 없습니까?) (0) | 2020.09.13 |
전체 WDK없이 windbg를 받고 있습니까? (0) | 2020.09.13 |