web-dev-qa-db-fra.com

Utiliser jQuery pour remplacer une balise par une autre

Objectif:

En utilisant jQuery, j'essaie de remplacer toutes les occurrences de:

<code> ... </code>

avec:

<pre> ... </pre>

Ma solution:

Je suis allé aussi loin que ce qui suit,

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

Le problème avec ma solution:

mais le problème est qu’il remplace tout entre les balises "code" (deuxième, troisième, quatrième, etc.) par le contenu situé entre les balises "(code) première".

par exemple.

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

devient

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

Je pense que je dois utiliser "ceci" et une sorte de fonction, mais j'ai bien peur d'apprendre encore et je ne comprends pas vraiment comment rassembler une solution.

97
jon

Vous pouvez transmettre une fonction à .replaceWith[docs] :

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

Dans la fonction, this fait référence à l'élément code en cours de traitement.

[~ # ~] démonstration [~ # ~]

Mise à jour: Il y a pas de grande différence de performances , mais au cas où les éléments code auraient d'autres enfants HTML, ajouter les enfants au lieu de les sérialiser semble plus correct:

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

C'est beaucoup mieux:

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

Bien que certes la solution de Felix Kling est approximativement deux fois plus vite :

79
Jens Roland

Il est exact que vous obtiendrez toujours le premier contenu de code, car $('code').html() fera toujours référence au premier élément, où que vous l'utilisiez.

Au lieu de cela, vous pouvez utiliser .each pour parcourir tous les éléments et les modifier individuellement:

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

Essaye ça:

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

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

});

http://jsfiddle.net/mTGhV/

11
Kokos

Que dis-tu de ça?

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

Construire sur la réponse de Felix.

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

Cela reproduira les attributs des balises code dans les balises de remplacement pre.

Edit: Ceci remplacera même les tags code qui se trouvent dans le innerHTML des autres tags 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');
5
tewathia

À partir de jQuery 1.4.2:

$('code').replaceWith(function(i,html) {
  return $('<pre />').html(html);
});​

Vous pouvez ensuite sélectionner les nouveaux éléments:

$('pre').css('color','red');

Source: http://api.jquery.com/replaceWith/#comment-45493689

jsFiddle: http://jsfiddle.net/k2swf/16/

2
Simon

Si vous utilisiez JavaScript Vanilla, vous devriez:

  • Créer le nouvel élément
  • Déplacez les enfants de l'ancien élément dans le nouvel élément
  • Insérer le nouvel élément avant l'ancien
  • Retirer l'ancien élément

Voici l'équivalent jQuery de ce processus:

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

Voici l'URL de jsperf:
http://jsperf.com/substituting- one-tag-for-another-with-jquery/7

PS: Toutes les solutions qui utilisent .html() ou .innerHTML Sont destructives.

1
Salman A

Un autre moyen simple et rapide:

$('code').wrapInner('<pre />').contents();
1
Fabian von Ellerts

Vous pouvez utiliser la fonction html de jQuery. Vous trouverez ci-dessous un exemple qui remplace une balise de code par une balise pré tout en conservant tous les attributs du code.

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

Cela pourrait fonctionner avec n'importe quel jeu de balises d'éléments HTML qui doivent être permutées tout en conservant tous les attributs de la balise précédente.

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

Meilleur et propre façon.

0
Nimek

Toutes les réponses données ici supposent (comme le montre l'exemple de question) qu'il n'y a pas d'attribut dans la balise. Si la réponse acceptée est exécutée sur ceci:

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

si sera remplacé par

<pre>A</pre>

Que faire si vous souhaitez conserver les attributs également? Que signifie remplacer une étiquette ...? Voici la solution:

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

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

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

Made jquery plugin, maintenant les attributs également.

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

Usage:

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