jQuery:如何更改标签名称?
jQuery:如何更改标签名称?
例如:
<tr> $1 </tr>
我需要
<div> $1 </div>
我可以
- 创buildDOM元素<div>
- 将tr内容复制到div
- 从dom中删除tr
但是,我可以直接吗?
PS:
$(tr).get(0).tagName = "div";
导致DOMException
。
您可以使用jQuery的.replaceWith()
方法replace任何HTML标记。
例如: http : //jsfiddle.net/JHmaV/
Ref .:。 用。。。来代替
如果你想保留现有的标记,你可以使用这样的代码:
$('#target').replaceWith('<newTag>' + $('target').html() +'</newTag>')
不,根据W3C规范是不可能的:“DOMStringtypes的tagName,只读”
DOM的renameNode()方法在哪里?
今天(2014)没有浏览器了解新的DOM3 renameNode方法 (请参阅W3C )检查是否运行在您的bowser: http : //jsfiddle.net/k2jSm/1/
所以,一个DOM解决scheme是丑陋的,我不明白为什么(?)jQuery没有实施一个解决方法?
纯DOMalgorithm
-
createElement(new_name)
- 将所有内容复制到新元素;
- 用
replaceChild()
replace旧的新的
是这样的,
function rename_element(node,name) { var renamed = document.createElement(name); foreach (node.attributes as a) { renamed.setAttribute(a.nodeName, a.nodeValue); } while (node.firstChild) { renamed.appendChild(node.firstChild); } return node.parentNode.replaceChild(renamed, node); }
…等待审查和jsfiddle …
jQueryalgorithm
@ilpoldoalgorithm是一个很好的起点,
$from.replaceWith($('<'+newname+'/>').html($from.html()));
正如其他人评论,它需要一个属性副本…等待通用…
特定于class
, 保留属性 ,请参阅http://jsfiddle.net/cDgpS/
要保留标签的内部内容,您可以使用访问器.html()
与.replaceWith()
分叉的例子: http : //jsfiddle.net/WVb2Q/1/
上述解决scheme将现有元素从头开始重新创build,并销毁进程中的任何事件绑定。
简短的回答:(失去的属性)
$("p").wrapInner("<div/>").children(0).unwrap();
更长的回答:(副本的属性)
$("p").each(function (o, elt) { var newElt = $("<div class='p'/>"); Array.prototype.slice.call(elt.attributes).forEach(function(a) { newElt.attr(a.name, a.value); }); $(elt).wrapInner(newElt).children(0).unwrap(); });
摆弄嵌套的绑定
从同一时间复制任何绑定将是一件很酷的事情,但获取当前的绑定对我来说并不适用。
你可以去一点基本的。 为我工作。
var oNode = document.getElementsByTagName('tr')[0]; var inHTML = oNode.innerHTML; oNode.innerHTML = ''; var outHTML = oNode.outerHTML; outHTML = outHTML.replace(/tr/g, 'div'); oNode.outerHTML = outHTML; oNode.innerHTML = inHTML;
要replace多个标签的内部内容,每个标签都有自己的原始内容,则必须以不同的方式使用.replaceWith()
和.html()
:
JS改变标签名称
/** * This function replaces the DOM elements's tag name with you desire * Example: * replaceElem('header','ram'); * replaceElem('div.header-one','ram'); */ function replaceElem(targetId, replaceWith){ $(targetId).each(function(){ var attributes = concatHashToString(this.attributes); var replacingStartTag = '<' + replaceWith + attributes +'>'; var replacingEndTag = '</' + replaceWith + '>'; $(this).replaceWith(replacingStartTag + $(this).html() + replacingEndTag); }); } replaceElem('div','span'); /** * This function concats the attributes of old elements */ function concatHashToString(hash){ var emptyStr = ''; $.each(hash, function(index){ emptyStr += ' ' + hash[index].name + '="' + hash[index].value + '"'; }); return emptyStr; }
相关小提琴在这个链接
简单地改变属性值就不会这样做(正如其他人所说的,一些HTMLElement
属性是只读的;也有一些将原型上下文保持为更原始的元素)。 模拟DOM API最接近的是模仿JavaScript中原型inheritance的过程。
通过__proto__
对象的原型的“设置”通常是不被接受的。 另外,您可能会考虑为什么您认为您需要首先复制整个DOM元素。 但是在这里:
// Define this at whatever scope you'll need to access it // Most of these kinds of constructors are attached to the `window` object window.HTMLBookElement = function() { function HTMLBookElement() { var book = document.createElement('book'); book.__proto__ = document.createElement('audio'); return book; } return new HTMLBookElement(); } // Test your new element in a console (I'm assuming you have Chrome) var harryPotter = new HTMLBookElement(); // You should have access to your new `HTMLBookElement` API as well as that // of its prototype chain; since I prototyped `HTMLAudioElement`, you have // some default properties like `volume` and `preload`: console.log(harryPotter); // should log "<book></book>" console.log(harryPotter.volume); // should log "1" console.log(harryPotter.preload); // should log "auto"
所有DOM元素都以这种方式工作。 例如: <div></div>
是由HTMLDivElement
生成的,它扩展了HTMLElement
,而HTMLElement
又扩展了Element
,后者又扩展了Object
。
由于replaceWith()
不适用于我的元素(可能是因为我在map()
使用它),我通过创build一个新元素并根据需要复制属性来完成此操作。
$items = $('select option').map(function(){ var $source = $(this), $copy = $('<li></li>'), title = $source.text().replace( /this/, 'that' ); $copy .data( 'additional_info' , $source.val() ) .text(title); return $copy; }); $('ul').append($items);
拿他的话
用Word“如何更改标签名称”的问题? 我会build议这个解决scheme:
如果有意义的话必须逐案决定。
我的例子将“重新命名”所有具有超链接的a-Tags,带有span标签的SMS。 维护所有属性和内容:
$('a[href^="sms:"]').each(function(){ var $t=$(this); var $new=$($t.wrap('<div>') .parent() .html() .replace(/^\s*<\s*a/g,'<span') .replace(/a\s*>\s*$/g,'span>') ).attr('href', null); $t.unwrap().replaceWith($new); });
因为它没有任何意义,有一个带有href属性的span标签,我也删除它。 这样做是防弹的,并与jQuery支持的所有浏览器兼容。 人们尝试将所有属性复制到新元素还有其他方法,但这些方法与所有浏览器都不兼容。
虽然我觉得用这种方法做起来相当昂贵。
jquery插件使“tagName”可编辑:
(function($){ var $newTag = null; $.fn.tagName = function(newTag){ this.each(function(i, el){ var $el = $(el); $newTag = $("<" + newTag + ">"); // attributes $.each(el.attributes, function(i, attribute){ $newTag.attr(attribute.nodeName, attribute.nodeValue); }); // content $newTag.html($el.html()); $el.replaceWith($newTag); }); return $newTag; }; })(jQuery);
见: http : //jsfiddle.net/03gcnx9v/3/
还有另一个脚本来改变节点名称
function switchElement() { $element.each(function (index, oldElement) { let $newElement = $('<' + nodeName + '/>'); _.each($element[0].attributes, function(attribute) { $newElement.attr(attribute.name, attribute.value); }); $element.wrapInner($newElement).children().first().unwrap(); }); }
http://jsfiddle.net/rc296owo/5/
它会将属性和内部html复制到一个新元素中,然后replace旧元素。
$(function(){ $('#switch').bind('click', function(){ $('p').each(function(){ $(this).replaceWith($('<div/>').html($(this).html())); }); }); });
p { background-color: red; } div { background-color: yellow; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <p>Hello</p> <p>Hello2</p> <p>Hello3</p> <button id="switch">replace</button>