代码之家  ›  专栏  ›  技术社区  ›  puchu

jquery:如何更改标记名?

  •  55
  • puchu  · 技术社区  · 14 年前

    jquery:如何更改标签名?

    例如:

    <tr>
        $1
    </tr>
    

    我需要

    <div>
        $1
    </div>
    

    是的,我能

    1. 创建dom元素<div>
    2. 将tr内容复制到div
    3. 从dom中删除tr

    但是我可以直接去吗?

    PS:

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

    结果在 DOMException .

    16 回复  |  直到 6 年前
        1
  •  35
  •   DLeh    9 年前

    可以使用jquery的 .replaceWith() 方法。

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

    Ref.:。 replaceWith

    如果要保留现有标记,可以使用以下代码:

    $('#target').replaceWith('<newTag>' + $('target').html() +'</newTag>')
    
        2
  •  43
  •   ggarber    14 年前

    不,根据W3C规范,“domstring类型的标记名,只读”是不可能的。

    http://www.w3.org/TR/DOM-Level-2-Core/core.html

        3
  •  13
  •   Peter Krauss    7 年前

    dom renamenode()方法在哪里?

    今天(2014年)没有浏览器了解 new DOM3 renameNode method (见 also W3C ) 检查您的弓箭手是否跑动: 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);
    }
    

    …等待审查和处理…

    jquery算法

    @ilpoldo算法是一个很好的起点,

       $from.replaceWith($('<'+newname+'/>').html($from.html()));
    

    正如其他人所评论的,它需要一个属性副本…等待常规…

    专用于 class , 保留属性 http://jsfiddle.net/cDgpS/

    也见 https://stackoverflow.com/a/9468280/287948

        4
  •  9
  •   ericP    7 年前

    上述解决方案将清除现有元素并从头开始重新创建它,从而销毁进程中子元素上的任何事件绑定。

    简短回答: (丢失的属性)

    $("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
  •  7
  •   ilpoldo    14 年前

    要保留标记的内部内容,可以使用访问器 .html() .replaceWith()

    分叉示例: http://jsfiddle.net/WVb2Q/1/

        6
  •  2
  •   Cory    10 年前

    你可以做一些基础的工作。为我工作。

    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;
    
        7
  •  1
  •   user856027    13 年前

    替换的内部内容 倍数 标签,每个标签都有自己的原始内容,您必须使用 .replaceWith() .html() 不同的:

    http://jsfiddle.net/kcrca/VYxxG/

        8
  •  1
  •   Shiva    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

        9
  •  1
  •   Dmitriy Sintsov    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')
    
        10
  •  0
  •   Benny Schmidt    11 年前

    仅仅改变房产价值是不行的(正如其他人所说,一些 HTMLElement 属性是只读的;还有一些属性将原型上下文保存到更原始的元素中)。最接近模仿domAPI的是模仿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 , 延伸 HTML-元素 , 依次延伸 Element , 依次延伸 Object .

        11
  •  0
  •   WoodrowShigeru    10 年前

    自从 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);
    
        12
  •  0
  •   Hannes Morgenstern    10 年前

    一言为定

    一个字接一个字地问:“如何更改标签名?”我建议这个解决方案:
    如果它有意义或没有,必须根据具体情况来决定。

    我的示例将“重命名”带有超链接的所有a-tags,用于带有span标记的短信息。维护所有属性和内容:

    $('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支持的所有浏览器兼容。 还有其他方法可以尝试将所有属性复制到新元素中,但这些方法与所有浏览器都不兼容。

    虽然我觉得这样做很贵。

        13
  •  0
  •   cedrik    9 年前

    jquery插件使“标记名”可编辑:

    (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/

        14
  •  0
  •   Berty    8 年前

    还有另一个脚本来更改节点名

    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到一个新元素中,然后替换旧元素。

        15
  •  0
  •   Ifeanyi Chukwu    7 年前

    $(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>
        16
  •  0
  •   Sarath Ak    7 年前

    你可以使用这个功能

    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');