कैसे jquery का उपयोग कर एक तत्व प्रकार को बदलने के लिए


104

मेरे पास निम्नलिखित कोड है

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

मैं bटैग को टैग में कैसे h1बदलूंगा लेकिन अन्य सभी विशेषताओं और जानकारी को रखूंगा?



@ बीनलैंड: यह गुण नहीं रखता है।
फेलिक्स क्लिंग

जवाबों:


137

यहाँ एक तरीका है जो आप इसे jQuery के साथ कर सकते हैं:

var attrs = { };

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


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

उदाहरण: http://jsfiddle.net/yapHk/

अद्यतन , यहाँ एक प्लगइन है:

(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);

उदाहरण: http://jsfiddle.net/mmNNJ/


2
@FelixKling: धन्यवाद, childrenकाम नहीं किया , लेकिन contentsकिया।
एंड्रयू व्हिटकर 1

1
@ और व्हाइटेकर वाह !!! तुम अच्छे हो! तो बस यह सुनिश्चित करने के लिए कि मैं b.class या b.xyzxterms का उपयोग करूं (xyzxterms वर्ग का नाम है)
bammab

5
@AndrewWhitaker: अगर मैं गलत नहीं हूँ, तो आपके प्लगइन में, सभी मिलान तत्वों के लिए पहले मिलान वाले तत्व की विशेषताएँ लागू होंगी। यह जरूरी नहीं है कि हम क्या चाहते हैं। जब सेट में तत्व का मिलान नहीं होता है तो भी एक त्रुटि होती है। यहां आपके प्लगइन का एक संशोधित संस्करण है जो प्रत्येक मिलान किए गए तत्वों के लिए अपनी विशेषताओं को रखता है और खाली सेट पर एक त्रुटि को ट्रिगर नहीं करता है: gist.github.com/2934516
Etienne

2
यह एक आकर्षण की तरह काम करता है! सिवाय इसके कि जब चयनकर्ता किसी भी मेलिंग तत्व को खोजने में विफल रहता है, तो यह कंसोल के लिए एक त्रुटि संदेश फेंकता है क्योंकि यह [0] अपरिभाषित एक्सेसिंग विशेषताओं को तोड़ता है। एक शर्त जोड़ने से यह ठीक हो जाता है: यदि (यह गति! = 0) {...
ciuncan

1
@ciuncan: प्रतिक्रिया के लिए धन्यवाद! यह वास्तव में .eachनीचे के शो की तरह एक ब्लॉक में भी लपेटा जाना चाहिए ।
एंड्रयू व्हिटकर

14

JQuery के बारे में निश्चित नहीं है। सादे जावास्क्रिप्ट के साथ आप कर सकते हैं:

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);

डेमो

यह सुनिश्चित नहीं है कि यह क्रॉस-ब्राउज़र संगत क्यों है।

एक भिन्नता हो सकती है:

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

अधिक जानकारी के लिए देखें Node.attributes [MDN]


आपके कोड का प्रदर्शन "शुद्ध jQuery" (उदा। एंड्रयू कोड) से बेहतर है, लेकिन आंतरिक टैग के साथ थोड़ी समस्या है, अपने कोड और संदर्भ-उदाहरण के साथ इस उदाहरण पर इटैलिक देखें ।
पीटर क्रूस

यदि आप सही करते हैं, तो एक "आदर्श jquery प्लगइन" को परिभाषित किया जा सकता है, आपके फ़ंक्शन को jquery- प्लगइन-टेम्पलेट द्वारा कॉल कर सकता है।
पीटर क्रूस

फिक्स्ड। समस्या यह थी कि पहले बच्चे की नकल करने के बाद, उसके पास अब अगला भाई-बहन नहीं है, इसलिए while(child = child.nextSibling)वह असफल रहा। धन्यवाद!
फेलिक्स क्लिंग

9

@ जाकोव और @Andrew Whitaker

यहां एक और सुधार किया गया है ताकि यह एक ही बार में कई तत्वों को संभाल सके।

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

3

@ जैज़बो के जवाब ने एक jQuery ऑब्जेक्ट लौटाया, जिसमें jQuery ऑब्जेक्ट्स की एक सरणी थी, जो चेनेबल नहीं थी। मैंने इसे बदल दिया है ताकि यह किसी वस्तु को $ .each के समान अधिक लौटाए।

    $.fn.changeElementType = function (newType) {
        var newElements,
            attrs,
            newElement;

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

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

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

            $(this).replaceWith(newElement);

            if (!newElements) {
                newElements = newElement;
            } else {
                $.merge(newElements, newElement);
            }
        });

        return $(newElements);
    };

(कुछ कोड क्लीनअप भी किया ताकि यह jslint से गुजर सके।)


यह सबसे अच्छा विकल्प की तरह लगता है। केवल एक चीज जो मुझे नहीं मिलती है वह यह है कि आपने इस.चेक () से बाहर होने वाले वेरिएशन के लिए var घोषणापत्र को स्थानांतरित कर दिया है। यह वहाँ छोड़ दिया के साथ ठीक काम करता है: jsfiddle.net/9c0k82sr/1
याकूब सी। कहते हैं, मोनिका

मैंने jslint की वजह से var को समूहीकृत किया: "(कुछ कोड क्लीनअप भी किया ताकि यह jslint पास हो।)"। इसके पीछे विचार यह है कि कोड को तेज किया जाए, मुझे लगता है (प्रत्येक eachलूप के भीतर varec redeclare करने के लिए नहीं )।
फिशचंदलारन

2

जिस तरह से मैं सोच सकता हूं कि सब कुछ मैन्युअल रूप से कॉपी करना है: उदाहरण jsfiddle

एचटीएमएल

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

JQuery / जावास्क्रिप्ट

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

2

@Andrew Whitaker: मैं इस बदलाव का प्रस्ताव करता हूं:

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

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

    var newelement = $("<" + newType + "/>", attrs).append($(this).contents());
    this.replaceWith(newelement);
    return newelement;
};

तब आप निम्न कार्य कर सकते हैं: $('<div>blah</div>').changeElementType('pre').addClass('myclass');


2

मुझे jQuery प्लगइन का उपयोग करने के लिए @AndrewWhitaker और अन्य का विचार पसंद है - changeElementType()विधि जोड़ने के लिए । लेकिन एक प्लगइन एक ब्लैकबॉक्स की तरह होता है, कोड के बारे में कोई मैटर नहीं करता है, अगर यह जला हुआ है और ठीक काम करता है ... तो, प्रदर्शन की आवश्यकता है, और कोड की तुलना में सबसे महत्वपूर्ण है।

"शुद्ध जावास्क्रिप्ट" का jQuery की तुलना में बेहतर प्रदर्शन है: मुझे लगता है कि @ FelixKling के कोड में @ एंड्रयूविटाकर और अन्य की तुलना में बेहतर प्रदर्शन है।


यहां एक "शुद्ध जावास्क्रिप्ट" (और "शुद्ध डोम") कोड, एक 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);

2

यहाँ एक विधि है जिसका उपयोग मैं html टैग को jquery में बदलने के लिए करता हूँ:

// Iterate over each element and replace the tag while maintaining attributes
$('b.xyzxterms').each(function() {

  // Create a new element and assign it attributes from the current element
  var NewElement = $("<h1 />");
  $.each(this.attributes, function(i, attrib){
    $(NewElement).attr(attrib.name, attrib.value);
  });

  // Replace the current element with the new one and carry over the contents
  $(this).replaceWith(function () {
    return $(NewElement).append($(this).contents());
  });

});

2

साथ jQuery के बिना विशेषताओं से अधिक पुनरावृत्ति:

replaceElemविधि नीचे स्वीकार करता है old Tag, new Tagऔर contextऔर प्रतिस्थापन सफलतापूर्वक कार्यान्वित:


replaceElem('h2', 'h1', '#test');

function replaceElem(oldElem, newElem, ctx) {
  oldElems = $(oldElem, ctx);
  //
  $.each(oldElems, function(idx, el) {
    var outerHTML, newOuterHTML, regexOpeningTag, regexClosingTag, tagName;
    // create RegExp dynamically for opening and closing tags
    tagName = $(el).get(0).tagName;
    regexOpeningTag = new RegExp('^<' + tagName, 'i'); 
    regexClosingTag = new RegExp(tagName + '>$', 'i');
    // fetch the outer elem with vanilla JS,
    outerHTML = el.outerHTML;
    // start replacing opening tag
    newOuterHTML = outerHTML.replace(regexOpeningTag, '<' + newElem);
    // continue replacing closing tag
    newOuterHTML = newOuterHTML.replace(regexClosingTag, newElem + '>');
    // replace the old elem with the new elem-string
    $(el).replaceWith(newOuterHTML);
  });

}
h1 {
  color: white;
  background-color: blue;
  position: relative;
}

h1:before {
  content: 'this is h1';
  position: absolute;
  top: 0;
  left: 50%;
  font-size: 5px;
  background-color: black;
  color: yellow;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>


<div id="test">
  <h2>Foo</h2>
  <h2>Bar</h2>
</div>

शुभ लाभ...


1
मुझे आपका जवाब पसंद है! क्यों? क्योंकि अन्य सभी उत्तर कुछ सरल करने के प्रयास में विफल रहेंगे जैसे एक एंकर को लेबल में बदलना। उस ने कहा, कृपया अपने उत्तर के लिए निम्नलिखित सुधारों / संशोधनों पर विचार करें: ए)। आपका कोड चयनकर्ताओं के साथ काम नहीं करेगा। बी) आपके कोड को असंवेदनशील रेगेक्स प्रदर्शन करना होगा। उस ने कहा, यहाँ मेरे सुझाए गए फ़िक्स हैं: regexOpeningTag = new RegExp ('^ <' + + (el) .get (0) .tagName, 'i'); regexClosingTag = new RegExp ($ (el) .get (0) .tagName + '> $', 'i');
zax

सादे HTML को इस तरह से बदलने से आप वस्तुओं से जुड़े किसी भी श्रोता को खो देंगे।
जोस यांज़ जूल

1

जावास्क्रिप्ट समाधान

पुराने तत्व की विशेषताओं को नए तत्व में कॉपी करें

const $oldElem = document.querySelector('.old')
const $newElem = document.createElement('div')

Array.from($oldElem.attributes).map(a => {
  $newElem.setAttribute(a.name, a.value)
})

पुराने तत्व को नए तत्व से बदलें

$oldElem.parentNode.replaceChild($newElem, $oldElem)

mapएक नया अप्रयुक्त सरणी बनाता है, इसे प्रतिस्थापित किया जा सकता है forEach
ओरखान अलीखानोव

1

यहाँ मेरा संस्करण है। यह मूल रूप से @ fiskhandlarn का संस्करण है, लेकिन एक नए jQuery ऑब्जेक्ट के निर्माण के बजाय, यह नए तत्वों के साथ पुराने तत्वों को अधिलेखित करता है, इसलिए कोई विलय आवश्यक नहीं है।
डेमो: http://jsfiddle.net/0qa7wL1b/

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

  this.each( function( index ){

    var atts = {};
    $.each( this.attributes, function(){
      atts[ this.name ] = this.value;
    });

    var $old = $(this);
    var $new = $('<'+ newType +'/>', atts ).append( $old.contents() );
    $old.replaceWith( $new );

    $this[ index ] = $new[0];
  });

  return this;
};
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.