Bir HTML etiketini kaldırın, ancak innerHtml'yi koruyun


152

Basit biçimlendirmeyi kaldırmam gereken bazı basit HTML'im var.

A nice house was found in <b>Toronto</b>.

Kalın harfleri kaldırmalıyım ama cümleyi olduğu gibi bırakmalıyım.

JQuery'de bu nasıl mümkün olabilir?

Yanıtlar:


304
$('b').contents().unwrap();

Bu, tüm seçer <b>, sonra unsurları kullanır.contents() metin içeriğini hedef <b>, daha sonra.unwrap() üst kaldırmak için <b>eleman.


En iyi performans için her zaman yerel olun:

var b = document.getElementsByTagName('b');

while(b.length) {
    var parent = b[ 0 ].parentNode;
    while( b[ 0 ].firstChild ) {
        parent.insertBefore(  b[ 0 ].firstChild, b[ 0 ] );
    }
     parent.removeChild( b[ 0 ] );
}

Bu, burada sağlanan herhangi bir jQuery çözümünden çok daha hızlı olacaktır.


1
+1 Orada oturup neredeyse aynı cevabı yazıyordum unwrap()ve metin kısmını nasıl alacağımı hatırlayamadım, unuttum .contents()- mükemmel.
38'de Orbling

2
Bu işe .replacewith()yarasa da, fazladan DOM geçişine kıyasla oldukça yavaştır ... <b>Yalnızca HTML içeren bir etiket ise daha da hızlı olur.
Nick Craver

Ayrıca, belirli bir aralığı veya yazı tipi etiketini açmak istiyorsanız, bunun gibi bir şey yapabilirsiniz: $ (". ClassName font"). Content () .wrap ();
Steve Cochrane

html <div> abc </div> ise abc kesme satırı tutulmaz mı? kesme satırı için <div> kullanırsanız nasıl tutabilirim? @ user113716
Hoa.Tran

1
Teşekkür ederim, bu çok yardımcı oldu. Bitişik metin düğümlerini birleştirmek için daha parent.normalize()sonra ekledim parent.removeChild(.... Sayfayı sürekli değiştiriyorsanız bu yardımcı oldu.
Justin Harris

53

Şu şekilde de kullanabilirsiniz .replaceWith():

$("b").replaceWith(function() { return $(this).contents(); });

Veya bunun sadece bir dizge olduğunu biliyorsanız:

$("b").replaceWith(function() { return this.innerHTML; });

Yukarıdaki yaklaşımlardan herhangi biri maliyetinden önemli ölçüde daha hızlı olduğu için , birçok öğeyi açıyorsanız bu büyük bir fark yaratabilir .unwrap().


Nick, cevabını da gerçekten beğendim. Diğerini seçtim çünkü bunu iPad uygulamamda (yerel veriler) kullanacağım etiket / metin miktarı küçük olduğu için performans çok önemli değil. Partick'in cevabı benim için biraz daha basit. Tüyleri 2 harika çözüme bölmek, ancak yalnızca bir çek verebilirim.
Ian Vink

1
@ BahaiResearch.com - Eğer performans bir sorun değilse, o zaman kesinlikle basitleşin ... Bunu sadece başkalarının daha sonra endişelenebilecekleri bulması için sağlıyorum :)
Nick Craver

Bu örneği bir textbox ile kullanmaya çalışıyordum ama bu beni öldürüyordu çünkü içindeki içerik sadece metin olarak görüntülenmekle kalmayıp değerlendirilmek istediğim html etiketleriydi. Kullanarak sona erdi: $ ['textarea']. ReplaceWith (function () {return $ (this) .val ();});
Will Sampson

13

İç html öğelerini kaldırmanın ve yalnızca metin döndürmenin en basit yolu JQuery .text () işlevidir .

Misal:

var text = $('<p>A nice house was found in <b>Toronto</b></p>');

alert( text.html() );
//Outputs A nice house was found in <b>Toronto</b>

alert( text.text() );
////Outputs A nice house was found in Toronto

jsFiddle Demosu


5

Buna ne dersin?

$("b").insertAdjacentHTML("afterend",$("b").innerHTML);
$("b").parentNode.removeChild($("b"));

İlk satır, betiketin HTML içeriğini etiketten hemen sonraki konuma kopyalar bve ardından ikinci satır, betiketi DOM'den kaldırarak yalnızca kopyalanmış içeriğini bırakır.

Normalde kullanımını kolaylaştırmak için bunu bir işleve sarıyorum:

function removeElementTags(element) {
   element.insertAdjacentHTML("afterend",element.innerHTML);
   element.parentNode.removeChild(element);
}

Kodun tamamı aslında saf Javascript, kullanılan tek JQuery, hedeflenecek öğeyi seçmektir ( bilk örnekteki etiket). İşlev sadece saf JS: D

Ayrıca şunlara da bakın:


3
// For MSIE:
el.removeNode(false);

// Old js, w/o loops, using DocumentFragment:
function replaceWithContents (el) {
  if (el.parentElement) {
    if (el.childNodes.length) {
      var range = document.createRange();
      range.selectNodeContents(el);
      el.parentNode.replaceChild(range.extractContents(), el);
    } else {
      el.parentNode.removeChild(el);
    }
  }
}

// Modern es:
const replaceWithContents = (el) => {
  el.replaceWith(...el.childNodes);
};

// or just:
el.replaceWith(...el.childNodes);

// Today (2018) destructuring assignment works a little slower
// Modern es, using DocumentFragment.
// It may be faster than using ...rest
const replaceWithContents = (el) => {
  if (el.parentElement) {
    if (el.childNodes.length) {
      const range = document.createRange();
      range.selectNodeContents(el);
      el.replaceWith(range.extractContents());
    } else {
      el.remove();
    }
  }
};

1

Başka bir yerel çözüm (kahvede):

el = document.getElementsByTagName 'b'

docFrag = document.createDocumentFragment()
docFrag.appendChild el.firstChild while el.childNodes.length

el.parentNode.replaceChild docFrag, el

User113716'nın çözümünden daha hızlı mı bilmiyorum, ancak bazıları için anlaşılması daha kolay olabilir.


1

En basit cevap akıllara durgunluk verecek:

OuterHTML , Internet Explorer 4'e kadar desteklenir !

İşte jQuery olmadan bile javascript ile yapmak

function unwrap(selector) {
    var nodelist = document.querySelectorAll(selector);
    Array.prototype.forEach.call(nodelist, function(item,i){
        item.outerHTML = item.innerHTML; // or item.innerText if you want to remove all inner html tags 
    })
}

unwrap('b')

Bu, eski IE dahil tüm ana tarayıcılarda çalışmalıdır. son tarayıcıda, nodelist üzerinden forEach'i bile çağırabiliriz.

function unwrap(selector) {
    document.querySelectorAll('b').forEach( (item,i) => {
        item.outerHTML = item.innerText;
    } )
}
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.