JavaScript'teki alt öğeleri değil, yalnızca ana öğe nasıl kaldırılır?


90

Diyelimki:

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

buna:

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

Mootools, jQuery ve hatta (ham) JavaScript kullanarak çözmeye çalışıyorum, ancak bunun nasıl yapılacağı hakkında bir fikre ulaşamadım.

Yanıtlar:


139

JQuery kullanarak bunu yapabilirsiniz:

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

Belgelere hızlı bağlantılar:


Keşke bunu 3 saat önce fark etseydim (hata .. buldum ) ... basit ve zarif - harika!
Tathagata

3
'cnt'nin anlamı nedir?
Steven Lu

1
'cnt', "içerikleri" tutan bir değişken adıdır
George Anderson

1
Neden olduğundan emin değilim, ancak bu içerik () kullanırken benim için işe yaramadı. Bununla birlikte, content () yerine html () kullandığımda, bir cazibe gibi çalıştı!
vertigoelectric

sadece 1 satırlık versiyon:$('.remove-just-this').replaceWith(function() { return $(this).html(); });
Taufik Nur Rahmanda

36

Kitaplıktan bağımsız yöntem, kaldırılacak öğenin tüm alt düğümlerini siz kaldırmadan önce kendisinden önce (bu onları eski konumlarından örtük olarak kaldırır) eklemektir:

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

nodeToBeRemoved.parentNode.removeChild(nodeToBeRemoved);

Bu, tüm alt düğümleri doğru sırayla doğru yere taşıyacaktır.


3
Modern JS bunu destekliyor:node.replaceWith(...node.childNodes);
Gibolt

34

Olay işleyicileri gibi şeyleri korumak için bunu DOM ile yaptığınızdan emin olmalısınız innerHTML(ve jk tarafından sağlanan jQuery çözümünü kullanıyorsanız innerHTMLdahili olarak kullanmak yerine DOM düğümlerini taşıdığından emin olun ).

Benim cevabım insin en çok benzer, ama daha iyi büyük yapıların (ayrı her düğümü ekleme CSS her biri için yeniden uygulanmaları sahiptir yeniden çizimlerin üzerinde yıpratıcı olabilir için sahne alacak appendChild; a ile DocumentFragment, bu yalnızca oluşur o sonrasına kadar görünür hale edilmez bir kez onun çocukların tümü eklenir ve belgeye eklenir).

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

Teşekkür ederim; kısa ve direkt.
brunoais


23

Daha zarif yol

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

2
En iyi cevap. Teşekkürler.
user706420

9

Modern JS kullanın!

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

oldNode.replaceWith(newNode) geçerli ES5

...array her dizi öğesini bir parametre olarak geçiren yayılma operatörüdür


2

Hangi kitaplığı kullanıyor olursanız olun, dış div'i DOM'dan kaldırmadan önce iç div'i klonlamanız gerekir. Sonra, klonlanmış iç div'i, dış div'in bulunduğu DOM'daki yere eklemeniz gerekir. Yani adımlar:

  1. Bir değişkende dış div'in üst öğesinin başvurusunu kaydedin
  2. İç div'i başka bir değişkene kopyalayın. Bu innerHTML, iç div'i bir değişkene kaydederek hızlı ve kirli bir şekilde yapılabilir veya iç ağacı düğümler halinde özyinelemeli olarak kopyalayabilirsiniz.
  3. removeChildDış div argüman olarak dış div'in ebeveynini çağırın .
  4. Kopyalanan iç içeriği, doğru konumda dış div'in üst öğesine ekleyin.

Bazı kütüphaneler bunların bir kısmını veya tamamını sizin için yapacak ancak yukarıdakine benzer bir şey başlık altında devam edecek.



1

Div'i içeriğiyle değiştirin:

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

Aynı şeyi pijamalarda yapmak istiyorsanız, işte böyle yapılır. harika çalışıyor (göz kapağına teşekkür ederim). Bu sayede, stilleri karıştırmadan düzgün bir şekilde yapan uygun bir zengin metin editörü yapabildim.

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
Bu hangi dil?
brunoais

Python'a benziyor - kullanıcı bahsettiğinden beri mantıklı pyjamas.
mgilson

0

Önemli bir DOM üzerinde çalışırken performans açısından en iyi yanıtı arıyordum .

gözkapaksızlığının cevabı, javascript kullanarak performansın en iyisi olduğuna işaret ediyordu.

Aşağıdaki yürütme süresi testlerini 5.000 satır ve 400.000 karakter üzerinde, bölümün içinde kaldırılacak karmaşık bir DOM bileşimi ile yaptım. JavaScript kullanırken uygun bir nedenle sınıf yerine bir kimlik kullanıyorum.

$ .Unwrap () kullanma

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

201,237 ms

$ .ReplaceWith () kullanarak

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

156,983 ms

Javascript'te DocumentFragment'ı kullanma

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

147,211 ms

Sonuç

Performans açısından, nispeten büyük bir DOM yapısında bile, jQuery ve javascript kullanımı arasındaki fark çok büyük değildir. Şaşırtıcı bir $.unwrap()şekilde en pahalı olanıdır $.replaceWith(). Testler jQuery 1.12.4 ile yapılmıştır.


0

Birden fazla satırla uğraşıyorsanız, benim kullanım durumumda olduğu gibi, muhtemelen şu satırlar boyunca bir şeyle daha iyi durumda olursunuz:

 $(".card_row").each(function(){
        var cnt = $(this).contents();
        $(this).replaceWith(cnt);
    });
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.