ลบแท็ก HTML แต่เก็บ InnerHtml ไว้


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() - ยอดเยี่ยม
Orbling

2
ในขณะที่ใช้งานได้ก็ยังค่อนข้างช้าเมื่อเทียบกับ.replacewith()เนื่องจากการข้ามผ่าน DOM พิเศษ ... หากเป็น<b>แท็กที่มี HTML เท่านั้นที่จะทำงานได้เร็วขึ้น
Nick Craver

นอกจากนี้หากคุณต้องการแกะสลักช่วงหรือแท็กแบบอักษรเฉพาะคุณสามารถทำสิ่งนี้: $ (". className font"). content (). unwrap ();
Steve Cochrane

หาก html คือ <div> abc </div> abc break line ไม่พัก? ฉันจะถือมันได้อย่างไรถ้าใช้ <div> สำหรับจุดพัก @ user113716
Hoa.Tran

1
ขอบคุณนี่มีประโยชน์มาก ฉันเพิ่มparent.normalize()หลังจากparent.removeChild(...รวมโหนดข้อความที่อยู่ติดกัน สิ่งนี้มีประโยชน์หากคุณกำลังแก้ไขหน้าอย่างต่อเนื่อง
Justin Harris

52

คุณสามารถใช้.replaceWith()เช่นนี้:

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

หรือถ้าคุณรู้ว่ามันเป็นเพียงแค่สตริง:

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

สิ่งนี้สามารถสร้างความแตกต่างได้มากหากคุณถอดองค์ประกอบหลายอย่างเนื่องจากวิธีการข้างต้นคือ เร็วกว่าต้นทุน.unwrap()อย่างมาก


นิคฉันชอบคำตอบของคุณเช่นกัน ฉันเลือกอีกอันเนื่องจากปริมาณแท็ก / ข้อความที่ฉันจะใช้ในแอพ iPad ของฉัน (ข้อมูลท้องถิ่น) มีขนาดเล็กดังนั้นประสิทธิภาพจึงไม่สำคัญ คำตอบของ Partick นั้นง่ายกว่าสำหรับฉันในการดูแลรักษา การแบ่งผมออกเป็น 2 โซลูชั่นที่ยอดเยี่ยม แต่ฉันสามารถตรวจสอบได้เพียงครั้งเดียว
Ian Vink

1
@ BahaiResearch.com - หากประสิทธิภาพไม่ใช่ปัญหาแล้วมันก็ง่ายมาก ... ฉันแค่ให้สิ่งนี้กับคนอื่น ๆ หามันในภายหลังซึ่งอาจจะกังวล :)
Nick Craver

ฉันพยายามใช้ตัวอย่างนี้กับกล่องข้อความ แต่มันฆ่าฉันเพราะเนื้อหาภายในเป็นแท็ก html ที่ฉันต้องการประเมินและไม่เพียงแสดงเป็นข้อความ ฉันลงเอยด้วยการใช้: $ ('textarea'). replaceWith (function () {return $ (this) .val ();});
Will Sampson

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

รหัสทั้งหมดเป็นจาวาสคริปต์แท้ๆ 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

ฉันไม่รู้ว่ามันเร็วกว่าโซลูชันของ user113716 หรือไม่ แต่อาจเข้าใจได้ง่ายกว่าสำหรับบางคน


1

คำตอบที่ง่ายที่สุดก็คือการเป่าใจ

outerHTMLรองรับจนถึง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;
    } )
}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.