web-dev-qa-db-ja.com

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、さらには(生の)JavaScriptを使用することを考えてきましたが、これを行う方法がわかりませんでした。

86
cheeaun

jQuery を使用すると、これを行うことができます。

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

ドキュメントへのクイックリンク:

132
jk.

ライブラリに依存しない方法は、削除する前に、削除する要素のすべての子ノードをそれ自体の前に挿入します(暗黙的にそれらを古い位置から削除します)。

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

nodeToBeRemoved.parentNode.removeChild(nodeToBeRemoved);

これにより、すべての子ノードが正しい順序で正しい場所に移動します。

36
Jonny Buchanan

innerHTMLではなく、DOMでこれを行う必要があります(jkが提供するjQueryソリューションを使用する場合は、innerHTMLを内部で使用するのではなく、DOMノードを移動することを確認してください)イベントハンドラーなどを保存します。

私の答えはinsinのものによく似ていますが、大きな構造の場合はパフォーマンスが向上します(各ノードを個別に追加すると、appendChildごとにCSSを再適用する必要がある再描画に負担がかかることがあります; DocumentFragmentでは、これが発生するだけです子がすべて追加されてドキュメントに追加されるまで表示されないため).

var fragment = document.createDocumentFragment();
while(element.firstChild) {
    fragment.appendChild(element.firstChild);
}
element.parentNode.replaceChild(fragment, element);
33
eyelidlessness
 $('.remove-just-this > *').unwrap()
27
campino2k

よりエレガントな方法は

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

最新の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_はスプレッド演算子で、各配列要素をパラメーターとして渡します

5
Gibolt

また、mootoolsでも試してみたので、mootoolsのソリューションを紹介します。

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

これは完全にテストされていませんが、以前にmootoolsを使用したことがあり、動作するはずです。

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

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

2
tj111

どちらのライブラリを使用する場合でも、DOMから外部divを削除する前に、内部divを複製する必要があります。次に、クローンされた内部divを、外部divがあったDOMの場所に追加する必要があります。手順は次のとおりです。

  1. 変数に外部divの親への参照を保存します
  2. 内側のdivを別の変数にコピーします。これは、内部divのinnerHTMLを変数に保存するか、ノードごとに内部ツリーを再帰的にコピーすることにより、迅速かつダーティーな方法で実行できます。
  3. 引数として外部divを使用して、外部divの親でremoveChildを呼び出します。
  4. コピーした内側のコンテンツを外側のdivの親の正しい位置に挿入します。

一部のライブラリはこれの一部またはすべてをあなたのために行いますが、上記のようなものは内部で行われます。

2
domgblackwell

これと同じことをパジャマで行いたい場合は、次のようにします。それはうまく機能します(まぶたに感謝します)。このおかげで、混乱することなくスタイルを適切に実行する適切なリッチテキストエディターを作成することができました。

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)
0
user362834

重要なDOMの作業中に、最良の答えperformance-wiseを探していました。

まぶたの答えは、JavaScriptを使用するとパフォーマンスが最高になると指摘していました。

削除するセクション内の複雑なDOM構成を使用して、5,000行と400,000文字で次の実行時間テストを行いました。 javascriptを使用する場合、便利な理由でクラスの代わりにIDを使用しています。

$。unwrap()を使用

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

201.237ms

$。replaceWith()を使用

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

156.983ms

javascriptで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とjavascriptの使用の違いはそれほど大きくありません。驚いたことに、$.unwrap()$.replaceWith()よりもコストが高くなります。テストはjQuery 1.12.4で行われました。

0
maxime_039

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

複数の行を処理している場合は、私のユースケースのように、おそらく次の行に沿って何かをした方が良いでしょう。

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