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?

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.


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, 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


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:


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

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.


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;
    } )
}
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.