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:blockify 内部td s 以及 tr,tr&gt;tddisplay:block 之类的东西。
【参考方案1】:

您可以使用 jQuery 的 .replaceWith() 方法替换任何 html 标记。

示例:http://jsfiddle.net/JHmaV/

参考:.replaceWith

如果你想保留现有的标记,你可以使用这样的代码:

$('#target').replaceWith('<newTag>' + $('#target').html() +'</newTag>')

【讨论】:

这行得通,但你不会继承 dom 元素的属性(样式、事件)等。我认为不存在真正实现完整节点名称更改的好方法。 抱歉,这不是“重命名”,它会破坏所有内容(所有 innerHTML 更改!)。 这是一个替换,而不是重命名! 为了保留内容的事件等,可以有.replaceWith($('&lt;newTag&gt;').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。 &lt;div data-divanslation="now you are in divouble"&gt;...&lt;/div&gt;【参考方案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 元素都以这种方式工作。例如: &lt;div&gt;&lt;/div&gt;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;
&lt;h1 class="test"&gt;Replace H1 to H2&lt;/h1&gt;

【讨论】:

以上是关于jQuery:如何更改标签名称?的主要内容,如果未能解决你的问题,请参考以下文章

Plotly:如何在 plotly express 折线图中更改图例的变量/标签名称?

如何更改标签栏控制器项目名称的字体大小?

使用jquery和javascript获取标签名称[重复]

如何更改 Netsuite 中标准字段的名称?

jQuery 中的 DOM 选择器,用于没有 ID 或 CLASS 名称标签的元素

如何在 matplotlib 中更改图例字体名称