Удалите тег HTML, но сохраните innerHtml

148

У меня есть простой HTML, который мне нужен для простого форматирования.

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

Мне нужно удалить жирный шрифт, но оставить предложение без изменений.

Как это возможно в jQuery?

Ян Винк
источник

Ответы:

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

При этом выбираются все <b>элементы, затем используется.contents() для нацеливания текстовое содержимое <b>, а затем.unwrap() для удаления его родительского <b>элемента.


Для достижения максимальной производительности всегда оставайтесь родным:

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

Это будет намного быстрее, чем любое решение jQuery, представленное здесь.

user113716
источник
1
+1 Я сидел там и писал почти одинаковый ответ относительно unwrap()и не мог вспомнить, как получить текстовую часть, забыл о .contents()- отлично.
Orbling
2
Хотя это работает, но это также довольно медленно по сравнению с .replacewith()дополнительным обходом DOM ... если это <b>тег только с HTML, он становится еще быстрее.
Ник Крейвер
Кроме того, если вы хотите просто развернуть определенный тег span или font, вы можете сделать что-то вроде этого: $ (". ClassName font"). Contents (). Unwrap ();
Стив Кокрейн,
если html <div> abc </ div> abc, строка разрыва не удерживается? как я могу держать его, если использовать <div> для разрыва строки? @ user113716
Hoa.Tran
1
Спасибо, это было очень полезно. Я добавил parent.normalize()после parent.removeChild(...слияния смежных текстовых узлов. Это было полезно, если вы постоянно изменяете страницу.
Джастин Харрис
52

Вы также можете использовать .replaceWith(), как это:

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

Или, если вы знаете, что это просто строка:

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

Это может иметь большое значение, если вы разворачиваете много элементов, поскольку любой из указанных выше подходов значительно быстрее, чем стоимость .unwrap().

Ник Крейвер
источник
Ник, мне очень нравится твой ответ. Я выбрал другой, потому что количество тегов / текста, для которого я буду использовать это в своем приложении для iPad (локальные данные), невелико, поэтому производительность не так уж важна. Ответ Партика немного проще для меня. Расщепление волос на 2 отличных решения, но я мог дать только один чек.
Ян Винк
1
@ BahaiResearch.com - Если производительность не является проблемой, тогда все будет просто ... Я просто предоставляю это для тех, кто найдет его позже, кто может быть обеспокоен этим :)
Ник Крейвер
Я пытался использовать этот пример с текстовым полем, но это убивало меня, потому что содержимое внутри было html-тегами, которые я хотел оценить, а не просто отображать в виде текста. В итоге я использовал: $ ('textarea'). ReplaceWith (function () {return $ (this) .val ();});
Уилл Сэмпсон
13

Самый простой способ удалить внутренние элементы html и вернуть только текст - это функция JQuery .text () .

Пример:

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
источник
5

Как насчет этого?

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

Первая строка копирует HTML-содержимое bтега в местоположение непосредственно после bтега, а затем вторая строка удаляет bтег из DOM, оставляя только его скопированное содержимое.

Я обычно заключаю это в функцию, чтобы упростить использование:

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

Весь код на самом деле является чистым Javascript, используется только JQuery для выбора целевого элемента ( bтег в первом примере). Функция просто чистая JS: D

Также посмотрите на:

Toastrackenigma
источник
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
источник
1

Еще одно нативное решение (в кофе):

el = document.getElementsByTagName 'b'

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

el.parentNode.replaceChild docFrag, el

Я не знаю, если это быстрее, чем решение user113716, но это может быть легче понять для некоторых.

GijsjanB
источник
1

Самый простой ответ - умопомрачительный:

externalHTML поддерживается вплоть до Internet Explorer 4!

Вот, чтобы сделать это с JavaScript даже без 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')

Это должно работать во всех основных браузерах, включая старые IE. в недавнем браузере мы можем даже вызывать forEach прямо в списке узлов.

function unwrap(selector) {
    document.querySelectorAll('b').forEach( (item,i) => {
        item.outerHTML = item.innerText;
    } )
}
izzulmakin
источник