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.