如何使用jQuery来更改元素types
我有下面的代码
<b class="xyzxterms" style="cursor: default; ">bryant keil bio</b>
如何将b
标签replace为h1
标签,但保留所有其他属性和信息?
下面是你可以用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/
不确定关于jQuery。 用普通的JavaScript你可以做到:
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
不知道这是如何跨浏览器兼容。
变化可能是:
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] 。
@雅科夫和@安德鲁·惠特克
这是一个进一步的改进,所以它可以同时处理多个元素。
$.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); };
只有我能想到的方式是手动复制一切: 例如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); });
@安德鲁·惠特克:我提出这个改变:
$.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');
我喜欢@AndrewWhitaker和其他人的想法,使用jQuery插件 – 添加changeElementType()
方法。 但是一个插件就像一个黑盒子,没有关于代码的function,如果它是litle,并且工作正常…所以,性能是必需的,并且比代码更重要。
“纯粹的JavaScript”比jQuery有更好的性能 :我认为@ FelixKling的代码比@ AndrewWhitaker和其他人有更好的性能。
这里有一个“纯Javavaccript”(和“纯DOM”)代码,封装成一个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);
这里是我用来取代jQuery中的HTML标签的方法:
// 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()); }); });
@ Jazzbo的答案返回了一个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。)