Javascript jQuery:如何更改标签名称?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 
原文地址: http://stackoverflow.com/questions/3435871/
Warning: these are provided under cc-by-sa 4.0 license.  You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
jQuery: how to change tag name?
提问by puchu
jQuery: how to change tag name?
jQuery:如何更改标签名称?
For example:
例如:
<tr>
    
</tr>
I need
我需要
<div>
    
</div>
Yes, I can
我可以
- Create DOM element <div>
 - Copy tr content to div
 - Remove tr from dom
 
- 创建 DOM 元素 <div>
 - 复制tr内容到div
 - 从dom中删除tr
 
But can I make it directly?
但是我可以直接做吗?
PS:
PS:
    $(tr).get(0).tagName = "div"; 
results in DOMException.
结果在DOMException.
采纳答案by jAndy
You can replace any HTML markup by using jQuery's .replaceWith()method.
您可以使用 jQuery 的.replaceWith()方法替换任何 HTML 标记。
example: http://jsfiddle.net/JHmaV/
示例:http: //jsfiddle.net/JHmaV/
Ref.: .replaceWith
参考:。用。。。来代替
If you want to keep the existing markup, you could use code like this:
如果要保留现有标记,可以使用如下代码:
$('#target').replaceWith('<newTag>' + $('#target').html() +'</newTag>')
回答by ggarber
No, it is not possible according to W3C specification: "tagName of type DOMString, readonly"
不,根据 W3C 规范,这是不可能的:“DOMString 类型的 tagName,只读”
回答by Peter Krauss
Where the DOM renameNode() Method?
DOM renameNode() 方法在哪里?
Today (2014) no browser understand the new DOM3 renameNode method(see also W3C) check if run at your bowser: http://jsfiddle.net/k2jSm/1/
今天(2014 年)没有浏览器了解新的 DOM3 renameNode 方法(另见W3C)检查是否在您的浏览器上运行:http: //jsfiddle.net/k2jSm/1/
So, a DOM solution is ugly and I not understand why (??) jQuery not implemented a workaround?
所以,DOM 解决方案很难看,我不明白为什么 (??) jQuery 没有实现解决方法?
pure DOM algorithm
纯DOM算法
createElement(new_name)- copy all content to new element;
 - replace old to new by 
replaceChild() 
createElement(new_name)- 将所有内容复制到新元素;
 - 将旧的替换为新的 
replaceChild() 
is something like this,
是这样的,
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);
}
... wait review and jsfiddle ...
...等待和jsfiddle ...
jQuery algorithm
jQuery 算法
The @ilpoldo algorithm is a good start point,
@ilpoldo 算法是一个很好的起点,
   $from.replaceWith($('<'+newname+'/>').html($from.html()));
As others commented, it need a attribute copy ... wait generic ...
正如其他人评论的那样,它需要一个属性副本......等待通用......
specific for class, preserving the attribute, see http://jsfiddle.net/cDgpS/
具体来说class,保留属性,见http://jsfiddle.net/cDgpS/
回答by ericP
The above solutions wipe out the existing element and re-create it from scratch, destroying any event bindings on children in the process.
上述解决方案清除现有元素并从头开始重新创建它,在此过程中破坏了子元素上的任何事件绑定。
short answer:(loses 's attributes)
简短回答:(丢失的属性)
$("p").wrapInner("<div/>").children(0).unwrap();
longer answer:(copies 's attributes)
更长的答案:(副本的属性)
$("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();
});
It would be cool to copy any bindings from the at the same time, but getting current bindingsdidn't work for me.
同时从 复制任何绑定会很酷,但获取当前绑定对我不起作用。
回答by ilpoldo
To preserve the internal content of the tag you can use the accessor .html()in conjunction with .replaceWith()
要保留标签的内部内容,您可以将访问.html()器与.replaceWith()
forked example: http://jsfiddle.net/WVb2Q/1/
分叉示例:http: //jsfiddle.net/WVb2Q/1/
回答by Dmitriy Sintsov
Inspired by ericPanswer, formatted and converted to jQuery plugin:
受ericP答案的启发,格式化并转换为 jQuery 插件:
$.fn.replaceWithTag = function(tagName) {
    var result = [];
    this.each(function() {
        var newElem = $('<' + tagName + '>').get(0);
        for (var i = 0; i < this.attributes.length; i++) {
            newElem.setAttribute(
                this.attributes[i].name, this.attributes[i].value
            );
        }
        newElem = $(this).wrapInner(newElem).children(0).unwrap().get(0);
        result.push(newElem);
    });
    return $(result);
};
Usage:
用法:
$('div').replaceWithTag('span')
回答by Cory
You could go a little basic. Works for me.
你可以做一些基本的。为我工作。
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;
回答by illusionist
JS to change the tag name
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;
}
Related fiddle is in this link
相关小提琴在此链接中
回答by user856027
To replace the internal contents of multipletags, each with their own original content, you have to use .replaceWith()and .html()differently:
要更换的内部内容的多个标签,每个都有自己的原创内容,您必须使用.replaceWith()和.html()不同的:
回答by Benny
Simply changing the property values won't do it (as others have said, some HTMLElementproperties are read-only; also some hold prototypal context to more primitive elements). The closest thing you can get to mimicking the DOM API is to mimic also the process of prototypal inheritance in JavaScript. 
简单地更改属性值是行不通的(正如其他人所说,有些HTMLElement属性是只读的;还有一些将原型上下文保存到更原始的元素)。最接近模仿 DOM API 的方法是模仿 JavaScript 中的原型继承过程。
'Setting' on an object's prototype via __proto__is generally frowned upon. Also, you might consider why you think you need to duplicate the entire DOM element in the first place. But here goes:
__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"
All DOM elements work this way. For example:
<div></div>is produced by HTMLDivElement,
which extends HTMLElement, 
which in turn extends Element,
which in turn extends Object.
所有 DOM 元素都以这种方式工作。例如:
<div></div>由 产生HTMLDivElement,它扩展HTMLElement,它又扩展Element,它又扩展Object。

