Bir etiketi diğeriyle değiştirmek için jQuery kullanma


101

Hedef:

JQuery kullanarak, şunların tüm oluşumlarını değiştirmeye çalışıyorum:

<code> ... </code>

ile:

<pre> ... </pre>

Çözümüm:

Şu kadar ileri gittim,

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

Çözümümle ilgili sorun:

ancak sorun, (ikinci, üçüncü, dördüncü vb.) "kod" etiketleri arasındaki her şeyi ilk "kod" etiketleri arasındaki içerikle değiştirmesidir .

Örneğin

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

olur

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

Sanırım "bu" ve bir tür işlev kullanmam gerekiyor ama korkarım hala öğreniyorum ve bir çözümü nasıl bir araya getireceğimi gerçekten anlamıyorum.


Sarma-sarma çözümü düzeltildi jon - kontrol edin;)
— Jens Roland

Yanıtlar:


157

Bir işlevi .replaceWith [dokümanlar] ' a aktarabilirsiniz :

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

İşlevin içinde, thisşu anda işlenen codeöğeyi ifade eder .

DEMO

Güncelleme: Orada hiçbir büyük performans farkı , ama durumda codeelemanları onları daha doğru olduğu hissediyor seri hale yerine çocukları ekleyerek, diğer HTML çocuk sahibi:

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

1
bu en zarif çözüm gibi görünüyor, bu yüzden replaceWith işlevinin içinde neler olup bittiğini anlamadığımı kabul ediyorum. daha fazlasını duymak isterim. ör. açılış VE kapanış etiketleri nasıl atanır? <pre /> içindeki boşluk bunu başarıyor mu?
— jon

2
@jon: Yeni unsurlar yaratmak için kısa bir el. Daha fazla bilgiyi burada bulabilirsiniz: api.jquery.com/jQuery/#jQuery2 . jQuery, tüm öğelerin üzerinde döngü oluşturur ve her biri için işlevi yürütür (yapılanla aynı .each).
— Felix Kling

@jon: Ama Jens'in çözümünü tekrar kontrol et, o düzeltti.
— Felix Kling

1
Güzel bir numara için +1 - bu, basit bir etiket yerine etiket değişiminden çok daha fazlası için kullanılabilir.
— Jens Roland

@FelixKling Bu, kod etiketlerinin özniteliklerinin üzerine yazılmaz mı?
— tewathia

80

Bu çok daha hoş:

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

Kuşkusuz Felix Kling'in çözümü yaklaşık iki kat daha hızlı :


4
bir cazibe gibi çalıştı, sıradan gözlerime göre bu en etkili çözüm gibi görünüyor. :)
— jon

Aha. evet, siz haklıydınız. benim için de işe yaramadı. bunu yakaladığınız için teşekkürler!
— jon

1
FWIW, $('code').children()yukarıdaki örnek için boş bir jQuery nesnesi döndürür, çünkü codeöğelerin alt öğe düğümleri yoktur. Alt öğeler varsa işe yarasa da .
— Felix Kling

1
Sabit - doğru, içerik tek bir metin düğümünden oluştuğunda children()çalışmıyor. contents()Bunun yerine kullanmak mükemmel çalışıyor. jsfiddle.net/7Yne9
— Jens Roland

1
İşte sayfayı bozmayan bir jsperf sürümü: jsperf.com/substituting-one-tag-for-another-with-jquery/2 ve görüyorsunuz artık hız farkı o kadar büyük değil. Çözümünüz daha yavaştır çünkü öğe başına iki DOM işlemi gerçekleştirirsiniz: unwrapüst öğeyi kaldırır ve alt öğeleri ağaca ekler, wraponları yeniden ayırır ve yeni bir üst öğe ekler.
— Felix Kling

26

Her zaman ilkini elde edeceğiniz doğru code$('code').html() ilk öğenin içeriğini , çünkü onu nerede kullanırsanız kullanın her zaman ilk öğeye atıfta bulunacaksınız.

Bunun yerine, .eachtüm öğeleri yinelemek ve her birini ayrı ayrı değiştirmek için kullanabilirsiniz :

$('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

Bunu dene:

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

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

});

http://jsfiddle.net/mTGhV/


vay. Siz ikiniz birbirinizden 2 saniye sonra aynı çözümü buldunuz. küçük biçimlendirme farklılıkları vardır. Hangisine oy vereceğimi bilmiyorum - thomas'ın cevabında function ile () arasındaki boşluğu gerçekten sevmiyorum ve kokos cevabındaki 2 satırlık boşluk oldukça nokta + () arasında bir boşluk olmalı ve {
— Michael Bylstra

11

Buna ne dersin?

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

6

Felix'in cevabını geliştirmek.

$('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;
});

Bu code, değiştirilen etiketlerin özniteliklerini yeniden oluşturacaktır.pre etiketlerindeki .

Düzenleme: Bu , diğer etiketlerin codeiçindeki etiketlerin bile yerini alacaktır .innerHTMLcode

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
Şimdiye kadarki en iyi cevap. Diğerlerinin hemen hemen hepsi aynı, bu da insanların onlara oy vermesi gerçekten tuhaf. Öznitelikleri düşünen tek kişi olduğunuz için tebrikler.
— Guilherme David da Costa


2

Vanilya JavaScript kullanıyorsanız şunları yaparsınız:

  • Yeni öğeyi oluşturun
  • Eski öğenin alt öğelerini yeni öğeye taşıyın
  • Yeni öğeyi eskisinin önüne ekleyin
  • Eski öğeyi kaldırın

İşte bu işlemin jQuery eşdeğeri:

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

İşte jsperf URL'si:
http://jsperf.com/substituting-one-tag-for-another-with-jquery/7

Not: Kullanım Bütün çözümler .html()veya .innerHTMLolan yıkıcı .



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

En iyi ve temiz yol.


0

JQuery'nin html işlevini kullanabilirsiniz. Aşağıda, kodun tüm özniteliklerini korurken, bir kod etiketini bir ön etiketle değiştiren bir örnek verilmiştir.

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

Bu, önceki etiketin tüm özniteliklerini korurken takas edilmesi gereken herhangi bir html öğe etiketi kümesiyle çalışabilir.


0

Yapılan jqueryda özelliklerini koruyarak, eklentisi.

$.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;
}

Kullanım:

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

0

Burada verilen tüm yanıtlar (soru örneğinin gösterdiği gibi) etiketinde hiçbir öznitelik olmadığını varsayar. Kabul edilen cevap bunun üzerine çalıştırılırsa:

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

ile değiştirilecekse

<pre>A</pre>

Ya öznitelikleri de korumak istiyorsanız - bir etiketi değiştirmenin anlamı nedir ...? Çözüm şudur:

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

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

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

Bunun birkaç yaşında olduğunu biliyorum ama sadece bahsetmek istedim ... html'yi önceki unsurdan korumayı unutmuşsun. Kod pasajınızda, alt öğelerin hiçbirini kopyalamadan, niteliklerle yeni bir öğe oluşturuyorsunuz.
— Bir Arkadaş

bu eklenerek yapılırcontent.html( this.html )
— patrick
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.