Supprimer une balise HTML mais conserver le innerHtml

148

J'ai du HTML simple dont j'ai besoin pour supprimer le formatage simple.

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

Je dois supprimer le gras, mais laissez la phrase intacte.

Comment est-ce possible dans jQuery?

Ian Vink
la source

Réponses:

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

Ceci sélectionne tous les <b>éléments, puis utilise.contents() pour cibler le contenu textuel de <b>, puis.unwrap() pour supprimer son <b>élément parent .


Pour des performances optimales, utilisez toujours le mode natif:

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

Ce sera beaucoup plus rapide que n'importe quelle solution jQuery fournie ici.

utilisateur113716
la source
1
+1 J'étais assis là à écrire une réponse presque identique concernant unwrap()et je ne me souvenais pas comment obtenir la partie de texte, j'ai oublié .contents()- excellent.
Orbling
2
Bien que cela fonctionne, il est également assez lent par rapport à .replacewith()la traversée supplémentaire du DOM ... si c'est une <b>balise avec uniquement du HTML, cela devient encore plus rapide.
Nick Craver
De plus, si vous souhaitez simplement dérouler une balise de span ou de police spécifique, vous pouvez faire quelque chose comme ceci: $ (". ClassName font"). Contents (). Unwrap ();
Steve Cochrane
si html est <div> abc </div> abc break line not hold? comment je peux le tenir si utiliser <div> pour la ligne de rupture? @ user113716
Hoa.Tran
1
Merci, cela m'a beaucoup aidé. J'ai ajouté parent.normalize()après parent.removeChild(...pour fusionner les nœuds de texte adjacents. Cela a été utile si vous modifiez continuellement la page.
Justin Harris le
52

Vous pouvez également utiliser .replaceWith(), comme ceci:

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

Ou si vous savez que ce n'est qu'une chaîne:

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

Cela peut faire une grande différence si vous déballez beaucoup d'éléments, car l'une ou l'autre des approches ci-dessus est beaucoup plus rapide que le coût de .unwrap().

Nick Craver
la source
Nick, j'aime beaucoup ta réponse aussi. J'ai choisi l'autre car la quantité de balises / texte que j'utiliserai dans mon application iPad (données locales) est petite, donc les performances ne sont pas trop importantes. La réponse de Partick est un peu plus simple pour moi à maintenir. Couper les cheveux sur 2 bonnes solutions, mais je ne pourrais en donner qu'une seule.
Ian Vink
1
@ BahaiResearch.com - Si les performances ne sont pas un problème, alors allez-y simplement ... Je le fournis simplement à d'autres personnes qui le trouveront plus tard et qui pourraient s'en inquiéter :)
Nick Craver
J'essayais d'utiliser cet exemple avec une zone de texte mais cela me tuait parce que le contenu à l'intérieur était des balises html que je voulais être évaluées et pas seulement affichées sous forme de texte. J'ai fini par utiliser: $ ('textarea'). ReplaceWith (function () {return $ (this) .val ();});
Will Sampson le
13

Le moyen le plus simple de supprimer les éléments HTML internes et de ne renvoyer que du texte serait la fonction JQuery .text () .

Exemple:

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

Démo jsFiddle

WebChemist
la source
5

Que dis-tu de ça?

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

La première ligne copie le contenu HTML de la bbalise à l'emplacement directement après la bbalise, puis la deuxième ligne supprime la bbalise du DOM, ne laissant que son contenu copié.

J'emballe normalement ceci dans une fonction pour le rendre plus facile à utiliser:

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

Tout le code est en fait pur Javascript, le seul JQuery utilisé est celui de sélectionner l'élément à cibler (la bbalise dans le premier exemple). La fonction est juste du pur JS: D

Regardez aussi:

Toastrackenigma
la source
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
la source
1

Une autre solution native (dans le café):

el = document.getElementsByTagName 'b'

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

el.parentNode.replaceChild docFrag, el

Je ne sais pas si c'est plus rapide que la solution de user113716, mais cela pourrait être plus facile à comprendre pour certains.

GijsjanB
la source
1

La réponse la plus simple est époustouflante:

externalHTML est pris en charge jusqu'à Internet Explorer 4!

Voici pour le faire avec javascript même sans jQuery

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

Cela devrait fonctionner dans tous les principaux navigateurs, y compris l'ancien IE. dans un navigateur récent, nous pouvons même appeler forEach à droite sur la liste de nœuds.

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