109 votes

comment changer le type d'un élément en utilisant jquery

J'ai le code suivant

<b class="xyzxterms" style="cursor: default; ">bryant keil bio</b>

Comment remplacer le b à une balise h1 mais conserver tous les autres attributs et informations ?

1 votes

0 votes

@beanland : Cela ne permet pas de conserver les attributs.

143voto

Andrew Whitaker Points 58588

Voici une façon de le faire avec jQuery :

var attrs = { };

$.each($("b")[0].attributes, function(idx, attr) {
    attrs[attr.nodeName] = attr.nodeValue;
});

$("b").replaceWith(function () {
    return $("<h1 />", attrs).append($(this).contents());
});

Exemple : http://jsfiddle.net/yapHk/

Mise à jour voici un plugin :

(function($) {
    $.fn.changeElementType = function(newType) {
        var attrs = {};

        $.each(this[0].attributes, function(idx, attr) {
            attrs[attr.nodeName] = attr.nodeValue;
        });

        this.replaceWith(function() {
            return $("<" + newType + "/>", attrs).append($(this).contents());
        });
    };
})(jQuery);

Exemple : http://jsfiddle.net/mmNNJ/

0 votes

+1 Nice. En ce qui concerne le contenu, vous pouvez le faire : $("<h1 />", attrs).append($(this).children()); . Cela permettrait également de préserver les données et les gestionnaires d'événements attachés aux nœuds enfants.

2 votes

@FelixKling : Merci, children n'a pas fonctionné mais contents a fait.

0 votes

Ah oui... ça devait être .contents() J'ai oublié les nœuds de texte.

17voto

Felix Kling Points 247451

Je ne suis pas sûr de jQuery. Avec un simple JavaScript, vous pourriez le faire :

var new_element = document.createElement('h1'),
    old_attributes = element.attributes,
    new_attributes = new_element.attributes;

// copy attributes
for(var i = 0, len = old_attributes.length; i < len; i++) {
    new_attributes.setNamedItem(old_attributes.item(i).cloneNode());
}

// copy child nodes
do {
    new_element.appendChild(element.firstChild);
} 
while(element.firstChild);

// replace element
element.parentNode.replaceChild(new_element, element);

DEMO

Je ne suis pas sûr de la compatibilité entre navigateurs.

Une variation pourrait être :

for(var i = 0, len = old_attributes.length; i < len; i++) {
    new_element.setAttribute(old_attributes[i].name, old_attributes[i].value);
}

Pour plus d'informations, voir Node.attributes [MDN] .

0 votes

Les performances de votre code sont meilleures que celles du "pur jQuery" (ex. le code d'Andrew), mais j'ai un petit problème avec les balises intérieures, voir l'italique à l'adresse suivante cet exemple avec votre code et le exemple de référence .

0 votes

Si tu es correct, Un "plugin jquery idéal". peut être défini, en appelant votre fonction par le jquery-plugin-template.

0 votes

Réparé. Le problème était qu'après la copie sur le premier enfant, il n'a plus de frère ou soeur suivant, donc while(child = child.nextSibling) échoué. Merci !

10voto

Jazzbo Points 41

@jakov et @Andrew Whitaker

Voici une nouvelle amélioration qui lui permet de traiter plusieurs éléments à la fois.

$.fn.changeElementType = function(newType) {
    var newElements = [];

    $(this).each(function() {
        var attrs = {};

        $.each(this.attributes, function(idx, attr) {
            attrs[attr.nodeName] = attr.nodeValue;
        });

        var newElement = $("<" + newType + "/>", attrs).append($(this).contents());

        $(this).replaceWith(newElement);

        newElements.push(newElement);
    });

    return $(newElements);
};

2voto

Peter Krauss Points 1888

J'aime l'idée de @AndrewWhitaker et d'autres, d'utiliser un plugin jQuery -- pour ajouter l'élément changeElementType() méthode. Mais un plugin est comme une boîte noire, peu importe le code, s'il est petit et fonctionne bien... Ainsi, la performance est requise, et est plus importante que le code.

"Pure javascript" ont meilleure performance que jQuery : Je pense que le code de @FelixKling a de meilleures performances que celui de @AndrewWhitaker et d'autres.


Voici un code "pur Javavascript" (et "pur DOM"), encapsulé dans un plugin jQuery :

 (function($) {  // @FelixKling's code
    $.fn.changeElementType = function(newType) {
      for (var k=0;k<this.length; k++) {
       var e = this[k];
       var new_element = document.createElement(newType),
        old_attributes = e.attributes,
        new_attributes = new_element.attributes,
        child = e.firstChild;
       for(var i = 0, len = old_attributes.length; i < len; i++) {
        new_attributes.setNamedItem(old_attributes.item(i).cloneNode());
       }
       do {
        new_element.appendChild(e.firstChild);
       }
       while(e.firstChild);
       e.parentNode.replaceChild(new_element, e);
      }
      return this; // for chain... $(this)?  not working with multiple 
    }
 })(jQuery);

2voto

kasdega Points 4266

Le seul moyen auquel je pense est de tout copier manuellement : exemple jsfiddle

HTML

<b class="xyzxterms" style="cursor: default; ">bryant keil bio</b>

Jquery/Javascript

$(document).ready(function() {
    var me = $("b");
    var newMe = $("<h1>");
    for(var i=0; i<me[0].attributes.length; i++) {
        var myAttr = me[0].attributes[i].nodeName;
        var myAttrVal = me[0].attributes[i].nodeValue;
        newMe.attr(myAttr, myAttrVal);
    }
    newMe.html(me.html());
    me.replaceWith(newMe);
});

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X