ใช้ jQuery เพื่อแทนที่แท็กหนึ่งด้วยอีกแท็ก


101

เป้าหมาย:

ใช้ jQuery ฉันพยายามแทนที่สิ่งที่เกิดขึ้นทั้งหมดของ:

<code> ... </code>

กับ:

<pre> ... </pre>

วิธีแก้ปัญหาของฉัน:

ฉันได้รับสิ่งต่อไปนี้

$('code').replaceWith( "<pre>" + $('code').html() + "</pre>" );

ปัญหาเกี่ยวกับวิธีแก้ปัญหาของฉัน:

แต่ปัญหาก็คือว่ามันเปลี่ยนทุกอย่างระหว่าง (ที่สองสามสี่ ฯลฯ ) "รหัส" แท็กที่มีเนื้อหาระหว่างที่แรก "รหัส" แท็ก

เช่น

<code> A </code>
<code> B </code>
<code> C </code>

กลายเป็น

<pre> A </pre>
<pre> A </pre>
<pre> A </pre>

ฉันคิดว่าฉันต้องใช้ "this" และฟังก์ชันบางอย่าง แต่ฉันกลัวว่าฉันยังคงเรียนรู้และไม่เข้าใจวิธีการแก้ปัญหาเข้าด้วยกัน


แก้ไขวิธีการแก้ปัญหาการห่อหุ้มตอนนี้ - ลองดูสิ;)
Jens Roland

คำตอบ:


157

คุณสามารถส่งผ่านฟังก์ชันไปยัง.replaceWith [docs] :

$('code').replaceWith(function(){
    return $("<pre />", {html: $(this).html()});
});

ภายในฟังก์ชันthisหมายถึงcodeองค์ประกอบที่ประมวลผลในปัจจุบัน

การสาธิต

อัปเดต:มีไม่แตกต่างกันประสิทธิภาพขนาดใหญ่แต่ในกรณีที่codeองค์ประกอบมีลูก HTML อื่น ๆ ผนวกเด็กแทน serializing พวกเขารู้สึกมีความถูกต้องมากขึ้น:

$('code').replaceWith(function(){
    return $("<pre />").append($(this).contents());
});

1
นี่ดูเหมือนจะเป็นวิธีแก้ปัญหาที่หรูหราที่สุดฉันจะยอมรับว่าฉันไม่เข้าใจว่าเกิดอะไรขึ้นภายในฟังก์ชัน replaceWith ชอบที่จะได้ยินมากขึ้น เช่นการกำหนดแท็กเปิดและปิดเป็นอย่างไร ช่องว่างใน <pre /> ทำสำเร็จหรือไม่
จอน

2
@jon: มันเป็นมือสั้นสำหรับการสร้างองค์ประกอบใหม่ ข้อมูลเพิ่มเติมสามารถพบได้ที่นี่: api.jquery.com/jQuery/#jQuery2 jQuery วนซ้ำองค์ประกอบทั้งหมดและเรียกใช้ฟังก์ชันสำหรับแต่ละองค์ประกอบ (เหมือนกับสิ่งที่.eachกำลังทำอยู่)
Felix Kling

@jon: แต่ตรวจสอบวิธีการแก้ปัญหาของ Jens อีกครั้งเขาแก้ไขแล้ว
Felix Kling

1
+1 สำหรับเคล็ดลับดีๆ - สิ่งนี้สามารถใช้ได้มากกว่าการทดแทนแท็กสำหรับแท็กง่ายๆ
Jens Roland

@FelixKling สิ่งนี้จะไม่เขียนทับแอตทริบิวต์ของแท็กโค้ดหรือไม่?
tewathia

80

นี่ดีกว่ามาก:

$('code').contents().unwrap().wrap('<pre/>');

แม้ว่าวิธีการแก้ปัญหาของ Felix Klingจะเร็วกว่าประมาณสองเท่า :


4
ทำงานได้อย่างมีเสน่ห์สำหรับดวงตาของฉันดูเหมือนว่านี่จะเป็นวิธีแก้ปัญหาที่มีประสิทธิภาพที่สุด :)
จอน

อ๊า. ใช่พวกคุณพูดถูก มันก็ไม่ได้ผลสำหรับฉันเช่นกัน ขอบคุณที่จับได้!
จอน

1
FWIW $('code').children()จะส่งคืนวัตถุ jQuery ที่ว่างเปล่าสำหรับตัวอย่างข้างต้นเนื่องจากcodeองค์ประกอบไม่มีโหนดองค์ประกอบลูก แม้ว่าจะใช้งานได้หากมีองค์ประกอบลูก
Felix Kling

1
คงที่ - จริงเมื่อเนื้อหาประกอบด้วยโหนดข้อความเดียวchildren()จะไม่ทำงาน การใช้contents()แทนทำงานได้อย่างสมบูรณ์ jsfiddle.net/7Yne9
Jens Roland

1
นี่คือเวอร์ชัน jsperf ที่ไม่ทำลายหน้า: jsperf.com/substituting-one-tag-for-another-with-jquery/2และคุณจะเห็นว่าความแตกต่างของความเร็วนั้นไม่ได้ใหญ่โตอีกต่อไป วิธีแก้ปัญหาของคุณช้าลงเนื่องจากคุณทำการปรับแต่ง DOM สองรายการต่อองค์ประกอบ: unwrapลบพาเรนต์และเพิ่มเด็กลงในทรีwrapแยกพวกมันอีกครั้งและเพิ่มพาเรนต์ใหม่
Felix Kling

26

ถูกต้องที่คุณจะได้รับcodeเนื้อหาแรก$('code').html()เสมอเพราะจะอ้างถึงองค์ประกอบแรกเสมอไม่ว่าคุณจะใช้งานใดก็ตาม

แต่คุณสามารถใช้.eachเพื่อทำซ้ำองค์ประกอบทั้งหมดและเปลี่ยนทีละองค์ประกอบ:

$('code').each(function() {
    $(this).replaceWith( "<pre>" + $(this).html() + "</pre>" );
    // this function is executed for all 'code' elements, and
    // 'this' refers to one element from the set of all 'code'
    // elements each time it is called.
});

12

ลองสิ่งนี้:

$('code').each(function(){

    $(this).replaceWith( "<pre>" + $(this).html() + "</pre>" );

});

http://jsfiddle.net/mTGhV/


ว้าว. พวกคุณคิดหาวิธีแก้ปัญหาเดียวกันภายใน 2 วินาทีซึ่งกันและกัน มีความแตกต่างในการจัดรูปแบบเล็กน้อย ฉันไม่แน่ใจว่าจะโหวตอันไหนดี - ฉันไม่ชอบช่องว่างระหว่างฟังก์ชันและ () ในคำตอบของ thomas และช่องว่าง 2 บรรทัดในคำตอบ kokos นั้นค่อนข้างตรงประเด็น + ควรมีช่องว่างระหว่าง () และ {
Michael Bylstra


6

สร้างคำตอบของเฟลิกซ์

$('code').replaceWith(function() {
    var replacement = $('<pre>').html($(this).html());
    for (var i = 0; i < this.attributes.length; i++) {
        replacement.attr(this.attributes[i].name, this.attributes[i].value);
    }
    return replacement;
});

สิ่งนี้จะสร้างแอตทริบิวต์ของcodeแท็กในการแทนที่preแท็ก

แก้ไข: สิ่งนี้จะแทนที่แม้กระทั่งcodeแท็กที่อยู่ในแท็กinnerHTMLอื่น ๆcode

function replace(thisWith, that) {
    $(thisWith).replaceWith(function() {
        var replacement = $('<' + that + '>').html($(this).html());
        for (var i = 0; i < this.attributes.length; i++) {
            replacement.attr(this.attributes[i].name, this.attributes[i].value);
        }
        return replacement;
    });
    if ($(thisWith).length>0) {
        replace(thisWith, that);
    }
}

replace('code','pre');

2
คำตอบที่ดีที่สุดจนถึงตอนนี้ คนอื่น ๆ ก็เหมือนกันหมดซึ่งแปลกจริงๆที่คนโหวตให้ ยินดีด้วยที่เป็นคนเดียวที่คิดเกี่ยวกับคุณลักษณะ
Guilherme David da Costa


2

หากคุณใช้วานิลลา JavaScript คุณจะ:

  • สร้างองค์ประกอบใหม่
  • ย้ายลูกขององค์ประกอบเก่าไปยังองค์ประกอบใหม่
  • แทรกองค์ประกอบใหม่ก่อนองค์ประกอบเก่า
  • ลบองค์ประกอบเก่า

นี่คือ jQuery เทียบเท่ากับกระบวนการนี้:

$("code").each(function () {
    $("<pre></pre>").append(this.childNodes).insertBefore(this);
    $(this).remove();
});

นี่คือ jsperf URL:
http://jsperf.com/substituting-one-tag-for-another-with-jquery/7

PS: การแก้ปัญหาทั้งหมดที่ใช้.html()หรือ.innerHTMLมีการทำลายล้าง



0
$('code').each(function(){
    $(this).replaceWith( "<pre>" + $(this).html()  + "</pre>" );
    });

วิธีที่ดีที่สุดและสะอาด


0

คุณสามารถใช้ฟังก์ชัน html ของ jQuery ด้านล่างนี้คือตัวอย่างที่แทนที่แท็กโค้ดด้วยแท็กก่อนหน้าในขณะที่ยังคงคุณสมบัติทั้งหมดของโค้ดไว้

    $('code').each(function() {
        var temp=$(this).html();
        temp=temp.replace("code","pre");
        $(this).html(temp);
    });

สิ่งนี้สามารถใช้ได้กับชุดของแท็กองค์ประกอบ html ที่จำเป็นต้องสลับในขณะที่ยังคงรักษาแอตทริบิวต์ทั้งหมดของแท็กก่อนหน้านี้


0

ทำjqueryปลั๊กอินรักษาคุณสมบัติด้วย

$.fn.renameTag = function(replaceWithTag){
  this.each(function(){
        var outerHtml = this.outerHTML;
        var tagName = $(this).prop("tagName");
        var regexStart = new RegExp("^<"+tagName,"i");
        var regexEnd = new RegExp("</"+tagName+">$","i")
        outerHtml = outerHtml.replace(regexStart,"<"+replaceWithTag)
        outerHtml = outerHtml.replace(regexEnd,"</"+replaceWithTag+">");
        $(this).replaceWith(outerHtml);
    });
    return this;
}

การใช้งาน:

$('code').renameTag('pre')

0

คำตอบทั้งหมดที่ให้ไว้ที่นี่ถือว่า (ตามที่ตัวอย่างคำถามระบุ) ว่าไม่มีแอตทริบิวต์ในแท็ก หากคำตอบที่ยอมรับถูกเรียกใช้ในสิ่งนี้:

<code class='cls'>A</code>

ถ้าจะถูกแทนที่ด้วย

<pre>A</pre>

จะเกิดอะไรขึ้นถ้าคุณต้องการเก็บแอตทริบิวต์ไว้ด้วย - สิ่งที่แทนที่แท็กจะหมายความว่าอย่างไร ... ? นี่คือวิธีแก้ปัญหา:

$("code").each( function(){
    var content = $( "<pre>" );

    $.each( this.attributes, function(){ 
         content.attr( this.name, this.value );
    } );

    $( this ).replaceWith( content );
} );

ฉันรู้ว่านี่อายุสองสามปีแล้ว แต่ฉันแค่คิดว่าจะพูดถึง ... คุณลืมเก็บ html จากองค์ประกอบก่อนหน้านี้ ในข้อมูลโค้ดของคุณคุณเพิ่งสร้างองค์ประกอบใหม่ที่มีแอตทริบิวต์โดยไม่ต้องคัดลอกส่วนย่อยใด ๆ เช่นกัน
A Friend

ที่จะทำได้โดยการเพิ่มcontent.html( this.html )
patrick
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.