Entfernen Sie ein HTML-Tag, aber behalten Sie das innerHtml bei

148

Ich habe etwas einfaches HTML, das ich brauche, um einfache Formatierungen zu entfernen.

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

Ich muss den Fettdruck entfernen, aber den Satz intakt lassen.

Wie ist das in jQuery möglich?

Ian Vink
quelle

Antworten:

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

Dies wählt alle <b>Elemente, dann verwendet.contents() den Textinhalt der zielen <b>, dann.unwrap() die Mutter entfernen <b>Element.


Für die beste Leistung gehen Sie immer einheimisch:

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 ] );
}

Dies ist viel schneller als jede hier bereitgestellte jQuery-Lösung.

user113716
quelle
1
+1 Ich saß da ​​und schrieb eine nahezu identische Antwort bezüglich unwrap()und konnte mich nicht erinnern, wie ich den Textteil bekommen sollte, vergessen .contents()- ausgezeichnet.
Orbling
2
Während dies funktioniert, ist es im Vergleich zu .replacewith()der zusätzlichen DOM-Durchquerung auch ziemlich langsam ... Wenn es sich um ein <b>Tag mit nur HTML handelt, wird es noch schneller.
Nick Craver
Wenn Sie nur einen bestimmten Bereich oder ein bestimmtes Schriftart-Tag auspacken möchten, können Sie Folgendes tun: $ (". ClassName font"). Content (). Unwrap ();
Steve Cochrane
wenn html ist <div> abc </ div> abc break line nicht halten? Wie kann ich es halten, wenn ich <div> für die Unterbrechungslinie verwende? @ user113716
Hoa.Tran
1
Danke, das war sehr hilfreich. Ich habe parent.normalize()nach hinzugefügt parent.removeChild(..., um benachbarte Textknoten zusammenzuführen. Dies war hilfreich, wenn Sie die Seite kontinuierlich ändern.
Justin Harris
52

Sie können auch Folgendes verwenden .replaceWith():

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

Oder wenn Sie wissen, dass es nur eine Zeichenfolge ist:

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

Dies kann einen großen Unterschied machen, wenn Sie viele Elemente auspacken, da jeder der oben genannten Ansätze erheblich schneller ist als die Kosten von .unwrap().

Nick Craver
quelle
Nick, ich mag deine Antwort auch sehr. Ich habe mich für den anderen entschieden, weil die Anzahl der Tags / Texte, für die ich dies in meiner iPad-App verwenden werde (lokale Daten), gering ist, sodass die Leistung nicht allzu wichtig ist. Particks Antwort ist für mich etwas einfacher zu pflegen. Haare teilen auf 2 tolle Lösungen, aber ich konnte nur einem den Scheck geben.
Ian Vink
1
@ BahaiResearch.com - Wenn Leistung kein Problem ist, dann gehen Sie einfach ... Ich biete dies nur für andere an, die es später finden und sich darüber Sorgen machen könnten :)
Nick Craver
Ich habe versucht, dieses Beispiel mit einem Textfeld zu verwenden, aber es hat mich umgebracht, weil der Inhalt darin HTML-Tags waren, die ausgewertet und nicht nur als Text angezeigt werden sollten. Am Ende habe ich Folgendes verwendet: $ ('textarea'). ReplaceWith (function () {return $ (this) .val ();});
Will Sampson
13

Der einfachste Weg, innere HTML-Elemente zu entfernen und nur Text zurückzugeben, wäre die Funktion JQuery .text () .

Beispiel:

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 Demo

WebChemist
quelle
5

Wie wäre es damit?

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

In der ersten Zeile wird der HTML-Inhalt des bTags direkt nach dem bTag an den Speicherort kopiert , in der zweiten Zeile wird der entferntb kopiert. In Tag aus dem DOM entfernt, wobei nur der kopierte Inhalt übrig bleibt.

Normalerweise verpacke ich dies in eine Funktion, um die Verwendung zu vereinfachen:

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

Der gesamte Code ist tatsächlich reines Javascript. Die einzige JQuery, die verwendet wird, ist die Auswahl des zu zielenden Elements (das b Tag im ersten Beispiel). Die Funktion ist nur reines JS: D.

Schauen Sie sich auch an:

Toastrackenigma
quelle
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();
    }
  }
};
Redisko
quelle
1

Eine andere native Lösung (in Kaffee):

el = document.getElementsByTagName 'b'

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

el.parentNode.replaceChild docFrag, el

Ich weiß nicht, ob es schneller als die Lösung von user113716 ist, aber für einige ist es möglicherweise einfacher zu verstehen.

GijsjanB
quelle
1

Die einfachste Antwort ist umwerfend:

OuterHTML wird bis zu Internet Explorer 4 unterstützt!

Hier ist es mit Javascript auch ohne jQuery zu tun

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')

Dies sollte in allen gängigen Browsern einschließlich des alten IE funktionieren. Im aktuellen Browser können wir sogar forEach direkt auf der Knotenliste aufrufen.

function unwrap(selector) {
    document.querySelectorAll('b').forEach( (item,i) => {
        item.outerHTML = item.innerText;
    } )
}
Izzulmakin
quelle