jQuery:如何更改标签名称?
Posted
技术标签:
【中文标题】jQuery:如何更改标签名称?【英文标题】:jQuery: how to change tag name? 【发布时间】:2011-03-27 00:55:50 【问题描述】:例如:
<tr>
$1
</tr>
我需要
<div>
$1
</div>
是的,我可以
- 创建 DOM 元素
将tr内容复制到div
从 dom 中移除 tr
但是我可以直接制作吗?
PS:
$(tr).get(0).tagName = "div";
结果为@987654325@。
【问题讨论】:
在这种特殊情况下,仅仅“重命名”它是没有意义的,因为div
不是tr
所在的有效元素。
查看这篇文章以获得包含所有属性的更完整的解决方案:***.com/questions/2815683/…
您也可以使用display:block
使tr
看起来像div
,而无需实际更改标签名称,但您可能希望display:block
ify 内部td
s 以及 tr,tr>tddisplay:block
之类的东西。
您可以使用 jQuery 的 .replaceWith()
方法替换任何 html 标记。
示例:http://jsfiddle.net/JHmaV/
参考:.replaceWith
如果你想保留现有的标记,你可以使用这样的代码:
$('#target').replaceWith('<newTag>' + $('#target').html() +'</newTag>')
【讨论】:
这行得通,但你不会继承 dom 元素的属性(样式、事件)等。我认为不存在真正实现完整节点名称更改的好方法。 抱歉,这不是“重命名”,它会破坏所有内容(所有 innerHTML 更改!)。 这是一个替换,而不是重命名! 为了保留内容的事件等,可以有.replaceWith($('<newTag>').append($('#target').contents())
【参考方案2】:
不,根据 W3C 规范,这是不可能的:“DOMString 类型的 tagName,只读”
http://www.w3.org/TR/DOM-Level-2-Core/core.html
【讨论】:
我的事情 que puchu 的问题只是关于“重命名过程”(!),并且有一个“DOM 丑陋的方式”来做重命名:1)createElement(new_name)
2)将所有内容复制到新元素; 3) 用replaceChild()
替换旧的到新的【参考方案3】:
DOM renameNode() 方法在哪里?
今天(2014)没有浏览器理解new DOM3 renameNode method(见also W3C) 检查是否在您的 Bowser 上运行:http://jsfiddle.net/k2jSm/1/
所以,DOM 解决方案很丑,我不明白为什么(??)jQuery 没有实现解决方法?
纯DOM算法
createElement(new_name)
将所有内容复制到新元素;
将旧的替换为新的replaceChild()
是这样的,
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 ...
jQuery 算法
@ilpoldo 算法是一个很好的起点,
$from.replaceWith($('<'+newname+'/>').html($from.html()));
正如其他人评论的那样,它需要一个属性副本......等待通用......
特定于class
,保留属性,见http://jsfiddle.net/cDgpS/
另见https://***.com/a/9468280/287948
【讨论】:
【参考方案4】:上述解决方案会清除现有元素并从头开始重新创建它,从而破坏进程中对子元素的任何事件绑定。
简短回答:(失去
的属性)$("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();
);
fiddle with nested bindings
同时从 复制任何绑定会很酷,但getting current bindings 对我不起作用。
【讨论】:
【参考方案5】:要保留标签的内部内容,您可以将访问器.html()
与.replaceWith()
结合使用
分叉示例:http://jsfiddle.net/WVb2Q/1/
【讨论】:
保存任何元素的所有属性怎么样? 正是我在搜索 +1 的内容。属性不包含在其他解决方案中,到目前为止,这是一个更好的解决方案 不,它不保留属性。 是的...但它的方向是正确的!它是一个“重命名过程”......用属性副本补充它,***.com/a/6753486/287948,或使用clone。【参考方案6】:灵感来自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);
;
用法:
$('div').replaceWithTag('span')
【讨论】:
【参考方案7】:工作纯 DOM 算法
function rename_element(node, name)
let renamed = document.createElement(name);
Array.from(node.attributes).forEach(attr =>
renamed.setAttribute(attr.name, attr.value);
)
while (node.firstChild)
renamed.appendChild(node.firstChild);
node.parentNode.replaceChild(renamed, node);
return renamed;
【讨论】:
非常现代的代码,并且有效。使用示例:$('blockquote').each(function()let ren = rename_element(this, 'div'); $(ren).doMoreJqueryStuff())
【参考方案8】:
你可以简单一点。对我有用。
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;
【讨论】:
它不是 jQuery 并且替换字符串不是安全或通用的策略,请使用 DOM 或 jQuery。<div data-divanslation="now you are in divouble">...</div>
【参考方案9】:
要替换多个标签的内部内容,每个标签都有自己的原始内容,你必须以不同的方式使用.replaceWith()
和.html()
:
http://jsfiddle.net/kcrca/VYxxG/
【讨论】:
这是@ilpoldo 解决方案的副本,并且可以更好地作为评论那里。必须删除复制解决方案。 我用这个作为 jquery mobile 有时会生成双选【参考方案10】: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;
相关的小提琴在这个link
【讨论】:
【参考方案11】:仅仅改变属性值是不行的(正如其他人所说,一些HTMLElement
属性是只读的;还有一些将原型上下文保存到更原始的元素)。最接近模仿 DOM API 的方法是模仿 javascript 中的原型继承过程。
通过__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
,
进而扩展Element
,
进而扩展Object
。
【讨论】:
@PeterKrauss 我不知道为什么我的答案在这里哈哈(它被移动了吗?)——这应该是“如何创建自定义 html 元素”的答案 嗯...检查“手指”发生了什么...***.com/posts/3435871/revisions(可能)是 *** 动态问题... 我听不懂你在说什么 对不起,我将删除:“手指”一词的含义(在 70 年代)是“是一个告密者”(而 UNIX 保留了几十年为finger
command流行)......我们可以说history of revisions like this 是用户操作的“手指”(或“告密者”)...嗯,“用户操作的动态(在 ***)”:可以是正常的,也可以是可以的是有问题的,因为当像您这样的人已经回答了问题的第一个版本时,用户可以更改问题。【参考方案12】:
由于replaceWith()
在元素基础上对我不起作用(可能是因为我在map()
中使用了它),所以我通过创建一个新元素并根据需要复制属性来做到这一点。
$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);
【讨论】:
【参考方案13】:言出必行
用单词回答“如何更改标签名称?”我会建议这个解决方案: 是否有意义,必须根据具体情况来决定。
我的示例将“重命名”所有带有超链接的 a-Tag,用于带有 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 支持的所有浏览器兼容。 人们还有其他方法尝试将所有属性复制到新元素,但这些方法并不与所有浏览器兼容。
虽然我认为这样做很昂贵。
【讨论】:
【参考方案14】: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/
【讨论】:
【参考方案15】:另一个脚本来更改节点名称
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 复制到一个新元素中,然后替换旧元素。
【讨论】:
【参考方案16】:$(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>
【讨论】:
【参考方案17】:你可以使用这个功能
var renameTag = function renameTag($obj, new_tag)
var obj = $obj.get(0);
var tag = obj.tagName.toLowerCase();
var tag_start = new RegExp('^<' + tag);
var tag_end = new RegExp('<\\/' + tag + '>$');
var new_html = obj.outerHTML.replace(tag_start, "<" + new_tag).replace(tag_end, '</' + new_tag + '>');
$obj.replaceWith(new_html);
;
ES6
const renameTag = function ($obj, new_tag)
let obj = $obj.get(0);
let tag = obj.tagName.toLowerCase();
let tag_start = new RegExp('^<' + tag);
let tag_end = new RegExp('<\\/' + tag + '>$');
let new_html = obj.outerHTML.replace(tag_start, "<" + new_tag).replace(tag_end, '</' + new_tag + '>');
$obj.replaceWith(new_html);
;
示例代码
renameTag($(tr),'div');
【讨论】:
【参考方案18】:也试试这个。在这个例子中,我们还可以在新标签中拥有旧标签的属性
var newName = document.querySelector('.test').outerHTML.replaceAll('h1', 'h2');
document.querySelector('.test').outerHTML = newName;
<h1 class="test">Replace H1 to H2</h1>
【讨论】:
以上是关于jQuery:如何更改标签名称?的主要内容,如果未能解决你的问题,请参考以下文章
Plotly:如何在 plotly express 折线图中更改图例的变量/标签名称?