Xóa thẻ HTML nhưng vẫn giữ bên trongHtml


148

Tôi có một số HTML đơn giản mà tôi cần phải loại bỏ định dạng đơn giản.

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

Tôi cần loại bỏ phần in đậm, nhưng giữ nguyên câu.

Làm thế nào điều này có thể trong jQuery?

Câu trả lời:


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

Cái này chọn tất cả các <b>phần tử, sau đó sử dụng.contents() để nhắm mục tiêu nội dung văn bản của <b>, sau đó.unwrap() loại bỏ <b>phần tử cha của nó .


Để có hiệu suất cao nhất, luôn luôn đi bản địa:

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

Điều này sẽ nhanh hơn nhiều so với bất kỳ giải pháp jQuery nào được cung cấp ở đây.


1
+1 Tôi đang ngồi đó viết ra một câu trả lời gần giống hệt nhau unwrap()và không thể nhớ làm thế nào để có được phần văn bản, quên đi .contents()- xuất sắc.
Orble

2
Mặc dù điều này hoạt động, nhưng nó cũng khá chậm so với .replacewith()vì truyền tải thêm DOM ... nếu đó là một <b>thẻ chỉ có HTML, nó thậm chí còn nhanh hơn.
Nick Craver

Ngoài ra, nếu bạn muốn mở khóa một khoảng hoặc thẻ phông cụ thể, bạn có thể làm một cái gì đó như thế này: $ (". ClassName font"). Content (). Unrap ();
Steve Cochrane

nếu html là <div> abc </ div> abc ngắt dòng không giữ? Làm thế nào tôi có thể giữ nó nếu sử dụng <div> cho dòng ngắt? @ user113716
Hoa.Tran

1
Cảm ơn bạn, điều này rất hữu ích. Tôi đã thêm parent.normalize()sau parent.removeChild(...để hợp nhất các nút văn bản liền kề. Điều này rất hữu ích nếu bạn liên tục sửa đổi trang.
Justin Harris

52

Bạn cũng có thể sử dụng .replaceWith(), như thế này:

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

Hoặc nếu bạn biết đó chỉ là một chuỗi:

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

Điều này có thể tạo ra sự khác biệt lớn nếu bạn hủy kết nối nhiều yếu tố vì cách tiếp cận ở trên nhanh hơn đáng kể so với chi phí .unwrap().


Nick, tôi thực sự thích câu trả lời của bạn là tốt. Tôi đã chọn cái khác vì số lượng thẻ / văn bản tôi sẽ sử dụng cho thẻ này trong ứng dụng iPad của tôi (dữ liệu cục bộ) là nhỏ nên hiệu suất không quá quan trọng. Câu trả lời của Partick đơn giản hơn một chút để tôi duy trì. Tách tóc trên 2 giải pháp tuyệt vời, nhưng tôi chỉ có thể đưa ra một tấm séc.
Ian Vink

1
@ BahaiResearch.com - Nếu hiệu suất không phải là vấn đề thì hoàn toàn đơn giản ... Tôi chỉ cung cấp điều này cho những người khác tìm thấy nó sau này, những người có thể quan tâm đến nó :)
Nick Craver

Tôi đã cố gắng sử dụng ví dụ này với một hộp văn bản nhưng nó đã giết chết tôi vì nội dung bên trong là các thẻ html mà tôi muốn được đánh giá và không chỉ hiển thị dưới dạng văn bản. Tôi đã kết thúc bằng cách sử dụng: $ ('textarea'). Thay thếWith (function () {return $ (this) .val ();});
Will Sampson

13

Cách đơn giản nhất để loại bỏ các phần tử html bên trong và chỉ trả về văn bản sẽ là hàm JQuery .text () .

Thí dụ:

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

Trình diễn jsFiddle


5

Còn cái này thì sao?

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

Dòng đầu tiên sao chép nội dung HTML của bthẻ vào vị trí ngay sau bthẻ và sau đó dòng thứ hai xóa bthẻ khỏi DOM, chỉ để lại nội dung được sao chép.

Tôi thường bọc cái này vào một chức năng để dễ sử dụng hơn:

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

Tất cả các mã thực sự là Javascript thuần túy, JQuery duy nhất đang được sử dụng là để chọn phần tử cần nhắm mục tiêu ( bthẻ trong ví dụ đầu tiên). Hàm này chỉ đơn thuần là JS: D

Cũng nhìn vào:


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

Một giải pháp bản địa khác (trong cà phê):

el = document.getElementsByTagName 'b'

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

el.parentNode.replaceChild docFrag, el

Tôi không biết nếu nó nhanh hơn giải pháp của user113716, nhưng đối với một số người có thể dễ hiểu hơn.


1

Câu trả lời đơn giản nhất là thổi tâm trí:

bên ngoàiHTML được hỗ trợ xuống Internet Explorer 4!

Đây là để làm điều đó với javascript ngay cả khi không có 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')

Điều này sẽ hoạt động trong tất cả các trình duyệt chính bao gồm IE cũ. trong trình duyệt gần đây, chúng ta thậm chí có thể gọi forEach ngay trên nút bấm.

function unwrap(selector) {
    document.querySelectorAll('b').forEach( (item,i) => {
        item.outerHTML = item.innerText;
    } )
}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.