Видаліть тег HTML, але зберігайте внутрішній HTML


148

У мене є простий HTML, який мені потрібен для простого форматування.

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

Мені потрібно зняти жирний шрифт, але речення залишити недоторканим.

Як це можливо в jQuery?

Відповіді:


301
$('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, що надається тут.


1
+1 Я сидів там і писав майже однакову відповідь щодо unwrap()і не міг пригадати, як отримати частину тексту, забув .contents()- чудово.
Орлінг

2
Хоча це працює, він також досить повільний порівняно .replacewith()з додатковим обходом DOM ... якщо це <b>тег лише HTML, він стає ще швидшим.
Нік Крейвер

Крім того, якщо ви хочете просто розгорнути певний проміжок або тег шрифту, ви можете зробити щось на зразок цього: $ (". Font font name"). Content (). Unrap ();
Стів Кокрайн

якщо 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 чудові рішення, але я міг дати лише один чек.
Ian Vink

1
@ BahaiResearch.com - Якщо продуктивність не є проблемою, то абсолютно просто ... Я просто надаю це іншим, хто їх пізніше знайде, хто може це хвилювати :)
Нік Крейвер

Я намагався використовувати цей приклад із текстовим полем, але це вбивало мене, оскільки вміст всередині був тегами HTML, який я хотів оцінити, а не просто відображати як текст. Я в кінцевому рахунку використовував: $ ('textarea'). SubstituWith (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


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

Також дивіться:


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

Ще одне нативне рішення (у каві):

el = document.getElementsByTagName 'b'

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

el.parentNode.replaceChild docFrag, el

Я не знаю, чи це швидше рішення користувача111116, але це може бути легше зрозуміти.


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. в останньому браузері ми навіть можемо зателефонувати за Кожен прямо у ноделісті.

function unwrap(selector) {
    document.querySelectorAll('b').forEach( (item,i) => {
        item.outerHTML = item.innerText;
    } )
}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.