如何在不删除子元素的情况下删除包装器(父元素)?

Posted

技术标签:

【中文标题】如何在不删除子元素的情况下删除包装器(父元素)?【英文标题】:How can I remove wrapper (parent element) without removing the child? 【发布时间】:2013-10-16 04:08:33 【问题描述】:

我想删除父级而不删除子级 - 这可能吗?

html 结构:

<div class="wrapper">
  <img src"">
</div>
<div class="button">Remove wrapper</div>

点击我想要的按钮后:

<img src"">
<div class="button">Remove wrapper</div>

【问题讨论】:

您可能会丢失附加到孩子的事件侦听器,但是是的,您可以这样做。 【参考方案1】:

可以使用这个 API:http://api.jquery.com/unwrap/

演示 http://jsfiddle.net/7GrbM/

.unwrap

代码将在以下几行中显示:

示例代码

$('.button').click(function()
    $('.wrapper img').unwrap();
);

【讨论】:

应该是$('.wrapper img').unwrap() 吗? +1 如果有更多内容则$('.wrapper').children().unwrap(); 谢谢哟! :) 你的 +1 被优雅地接受,为 OP 的更多东西干杯。 +1 如果(有时)只有文本内容(即没有子元素),那么$('.wrapper').contents().unwrap();【参考方案2】:

javascript 解决方案,我相信有人可以进一步简化它,但这是纯 javascript 人的替代方案。

HTML

<div class="button" onclick="unwrap(this)">Remove wrapper</div>

Javascript(纯)

function unwrap(i) 
    var wrapper = i.parentNode.getElementsByClassName('wrapper')[0];
    // return if wrapper already been unwrapped
    if (typeof wrapper === 'undefined') return false;
    // remmove the wrapper from img
    i.parentNode.innerHTML = wrapper.innerHTML + i.outerHTML;
    return true;

JSFIDDLE

【讨论】:

检查你的工作 fiddle 解包后的一些问题。修复它。 使用 innerHTML 是邪恶的,它会删除 HTML 中的所有事件。 @julmot 清楚...(:如果您想要一个解决方案,请向上或向下滚动,您会找到它。我不是在这里创建重复的答案,尤其是当问题没有'不要求保留事件处理程序。(;【参考方案3】:

很惊讶没有人发布最简单的答案:

// Find your wrapper HTMLElement
var wrapper = document.querySelector('.wrapper');

// Replace the whole wrapper with its own contents
wrapper.outerHTML = wrapper.innerHTML;

【讨论】:

即使你失去听众也很有趣【参考方案4】:

不使用innerHTML的纯JS解决方案:

function unwrap(wrapper) 
    // place childNodes in document fragment
    var docFrag = document.createDocumentFragment();
    while (wrapper.firstChild) 
        var child = wrapper.removeChild(wrapper.firstChild);
        docFrag.appendChild(child);
    

    // replace wrapper with document fragment
    wrapper.parentNode.replaceChild(docFrag, wrapper);

Try it:

unwrap(document.querySelector('.wrapper'));

【讨论】:

为什么最好避免使用innerHTML? @ajbeaven 保留现有的 DOM 对象(而不是使用 innerHTML 重新创建它们)意味着维护附加到它们的任何事件侦听器。 不错的解决方案,但是不需要从包装器中删除子节点,因为docFrag.appendChild(wrapper.firstChild); 会自动将节点从当前位置移动到新位置。 Read more about appendChild on MDN【参考方案5】:

如果您使用的是 jQuery:

$(".wrapper").replaceWith($(".wrapper").html());

【讨论】:

【参考方案6】:

如果包装元素包含文本,则文本将保留子节点。

【讨论】:

【参考方案7】:

纯 JS (ES2015) 解决方案,在我看来比 jQuery 解决方案更容易阅读。

node.replaceWith(...node.childNodes)

节点必须是ElementNode

const wrapperNode = document.querySelector('h1')
wrapperNode.replaceWith(...wrapperNode.childNodes)
<h1>
  <a>1</a>
  <b>2</b>
  <em>3</em>
</h1>

【讨论】:

带打字稿:const unwrap = (node: Element) =&gt; node.replaceWith(...Array.from(node.children)); ;

以上是关于如何在不删除子元素的情况下删除包装器(父元素)?的主要内容,如果未能解决你的问题,请参考以下文章

js删除一个父元素下面的所有子元素

JQuery中查找父元素,子元素,追加元素,插入元素和删除元素

node.js如何删除数组子文档的元素?

Jquery如何选取元素及其所有子元素?

如何根据子节点删除父节点和/或 css 样式

子元素不继承父元素中的点击事件