【问题标题】:jQuery: how to change tag name?jQuery:如何更改标签名称?
【发布时间】:2011-03-27 00:55:50
【问题描述】:

jQuery:如何更改标签名称?

例如:

<tr>
    $1
</tr>

我需要

<div>
    $1
</div>

是的,我可以

  1. 创建 DOM 元素
  2. 将tr内容复制到div
  3. 从 dom 中移除 tr
  4. 但是我可以直接制作吗?

    PS:

        $(tr).get(0).tagName = "div"; 
    

    结果为@​​987654325@。

【问题讨论】:

  • 在这种特殊情况下,仅仅“重命名”它是没有意义的,因为div 不是tr 所在的有效元素。
  • 查看这篇文章以获得包含所有属性的更完整的解决方案:stackoverflow.com/questions/2815683/…
  • 您也可以使用display:block 使tr 看起来像div,而无需实际更改标签名称,但您可能希望display:blockify 内部td s 以及 tr,tr&gt;td{display:block} 之类的东西。

标签: javascript jquery html dom dhtml


【解决方案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算法

  1. createElement(new_name)
  2. 将所有内容复制到新元素;
  3. 将旧的替换为新的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://stackoverflow.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 的内容。属性不包含在其他解决方案中,到目前为止,这是一个更好的解决方案
      • 不,它不保留属性。
      • 是的...但它的方向是正确的!它是一个“重命名过程”......用属性副本补充它,stackoverflow.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 元素”的答案
          • 嗯...检查“手指”发生了什么...stackoverflow.com/posts/3435871/revisions(可能)是 Stackoverflow 动态问题...
          • 我听不懂你在说什么
          • 对不起,我将删除:“手指”一词的含义(在 70 年代)是“是一个告密者”(而 UNIX 保留了几十年为finger command流行)......我们可以说history of revisions like this 是用户操作的“手指”(或“告密者”)...嗯,“用户操作的动态(在 Stackoverflow)”:可以是正常的,也可以是可以的是有问题的,因为当像您这样的人已经回答了问题的第一个版本时,用户可以更改问题。
          【解决方案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;

                      【讨论】:

                        猜你喜欢
                        相关资源
                        最近更新 更多
                        热门标签