【问题标题】:Change HTML element type更改 HTML 元素类型
【发布时间】:2012-12-13 13:01:10
【问题描述】:

我可以用另一个 HTML 元素替换一个 HTML 元素吗?

但我不想将内容设为空白。

发件人:

<a data-text="text">content</a>

到:

<div data-text="text">content</div>

有什么想法吗?

【问题讨论】:

  • href 不是 div 标签的有效属性
  • 一种可能的用途(以及我找到此线程的原因)可能是用于将 Google 文档中的 斜体替换为 标记的书签.

标签: javascript jquery html


【解决方案1】:

2018 年更新:

使用ChildNode.replaceWith() 方法。如 MDN 文档所示:

var parent = document.createElement("div");
var child = document.createElement("p");
parent.appendChild(child);
var span = document.createElement("span");

child.replaceWith(span);

console.log(parent.outerHTML);
// "<div><span></span></div>"

更多信息在this answer

【讨论】:

【解决方案2】:

没有。您不能更改 DOM 节点的tagName (nodeName)。

您只能创建所需类型的新节点,复制所有属性(可能还有属性)并移动子节点。但是,您会丢失无法访问的东西,例如附加的事件侦听器。例如,当您想change the type of an input in IE 时使用此技术。

但是,绝对没有理由将 a 更改为 div,它们具有完全不同的语义(包括行为和布局)。

【讨论】:

    【解决方案3】:

    这是解决此问题的更现代(2022 年以上)的方法。

    基本上你创建一个新元素,将属性传递给它,然后传递子元素,最后用新元素替换元素。

    我还为&lt;svg&gt; 等区分大小写的元素提供了一个示例。出于区分大小写的目的,您不应使用innerHTML。而是使用 while 循环和 appendChild

    function changeTag (node, tag) {
      const clone = createElement(tag)
      for (const attr of node.attributes) {
        clone.setAttributeNS(null, attr.name, attr.value)
      }
      while (node.firstChild) {
        clone.appendChild(node.firstChild)
      }
      node.replaceWith(clone)
      return clone
    }
    
    function createElement (tag) {
      if (tag === 'svg') {
        return document.createElementNS('http://www.w3.org/2000/svg', 'svg')
      } else {
        return document.createElementNS('http://www.w3.org/1999/xhtml', tag)
      }
    }
    
    const node1 = document.getElementById('node1')
    console.log(node1.outerHTML)
    console.log(changeTag(node1, 'a').outerHTML)
    
    const node2 = document.getElementById('node2')
    console.log(node2.outerHTML)
    console.log(changeTag(node2, 'svg-custom').outerHTML)
    <p id="node1" class="x" rel="follow">
      Some <b class="a1">bold</b> text
    </p>
    
     <svg id="node2" height="150" width="400">
      <defs>
        <linearGradient id="grad1" x1="0%" y1="0%" x2="100%" y2="0%">
          <stop offset="0%" style="stop-color:rgb(255,255,0);stop-opacity:1" />
          <stop offset="100%" style="stop-color:rgb(255,0,0);stop-opacity:1" />
        </linearGradient>
      </defs>
      <ellipse cx="200" cy="70" rx="85" ry="55" fill="url(#grad1)" />
    </svg>

    【讨论】:

      【解决方案4】:

      当然,但是为什么呢?

      var a = ​document.getElementsByTagName('a');
      var src, el, attrs;
      for(var i=0,l=a.length;i<l;i++) {
          src = a[i];
          el = document.createElement('div');
          attrs = src.attributes;
          for(var j=0,k=attrs.length;j<k;j++) {
              el.setAttribute(attrs[j].name, attrs[j].value);
          }
          el.innerHTML = src.innerHTML;
          src.parentNode.replaceChild(el, src);
      }
      

      【讨论】:

      • 不要使用innerHTML进一步分离节点。
      【解决方案5】:

      这将是无效的 HTML(div 元素没有 href 属性)并且不再像链接一样。

      但是,您可以使用 JavaScript 模拟该行为:

      $('div').on('click', function() {
          location.href = $(this).attr('href');
      });
      

      但请不要这样做。例如,它会破坏鼠标中键(对于新标签)。

      【讨论】:

        【解决方案6】:

        这是在您的 HTML 代码中执行此操作的简单方法。通过一些嵌入式样式和 javascript 代码,这将为您提供您正在寻找的效果......

        <div style="display: inline; color: blue;" onclick="window.location='link/url';">Click!</div>
        

        【讨论】:

          【解决方案7】:

          使用

          var href=$("#aId").attr('href');
          
          $("#aId").replaceWith($("<div"+href+">" + $("#aId").innerHTML + "</div>"));
          

          【讨论】:

            【解决方案8】:

            简短的现代香草方式

            const atts = Array.prototype.slice.call(elem.attributes)
            elem.outerHTML = `<div ${atts.map(
              attr => (attr.name + '="' + attr.value + '"')
            ).join(' ')}>${elem.innerHTML}</div>`
            

            此解决方案将转换您的标签名称并保留所有属性,而无需您自己从 DOM 中删除和添加元素。浏览器会为您处理,因此您必须从 DOM 重新加载元素才能在转换后访问它。

            示例

            let elem = document.getElementById("test")
            const tagName = 'div'
            
            const atts = Array.prototype.slice.call(elem.attributes)
            elem.outerHTML = `<${tagName} ${atts.map(
              attr => (attr.name + '="' + attr.value + '"')
            ).join(' ')}>${elem.innerHTML}</${tagName}>`
            
            elem = document.getElementById("test") // reload required
            console.log(elem.outerHTML)
            &lt;span id="test" data-test="123"&gt;I want to be a div.&lt;/span&gt;

            不需要保留属性?

            elem.outerHTML = `<div id="test">${elem.innerHTML}</div>`
            

            这一行会做,但请记住elem 将指向旧元素,就像在上面的解决方案中一样。

            示例

            let elem = document.getElementById("test")
            const tagName = 'div'
            
            elem.outerHTML = `<${tagName} id="test">${elem.innerHTML}</${tagName}>`
            
            elem = document.getElementById("test") // reload required
            console.log(elem.outerHTML)
            &lt;span id="test"&gt;I want to be a div.&lt;/span&gt;

            使用这些方法,您总是需要从 DOM 重新加载对象才能继续使用它,因为浏览器会创建一个新的 DOM 元素并将其放置在后台。

            【讨论】:

              【解决方案9】:

              这是一种无需 jQuery 即可更改元素标签的方法 -

              // Just provide the element and the new tag
              
              function changeTag(el, newTag) {
                  var outerHTML = el.outerHTML // Get the outerHTML of the element
                  var tag = el.tagName // Get the tag of the outerHTML
                  var r = new RegExp(tag, 'i') // Prepare a RegExp to replace the old tag with the new tag
                  outerHTML = outerHTML.replace(r, newTag) // Replace it
                  el.outerHTML = outerHTML // Set the outerHTML of the element
              }
              <span>Span 1</span> -- <span>Span 2</span>
              <br>
              <button onclick="changeTag(document.querySelector('span'), 'div')">
              Change tag
              </button>

              【讨论】:

                【解决方案10】:
                <input id="tmpType" type="text" name="password" />
                
                <script type="text/javascript">
                    document.getElementById('tmpType').type = 'password';
                </script>
                

                我用它在动态表单上显示/隐藏密码

                【讨论】:

                  猜你喜欢
                  • 2017-07-02
                  • 1970-01-01
                  • 2022-07-19
                  • 2013-12-03
                  • 1970-01-01
                  • 2012-04-28
                  • 2012-01-24
                  • 1970-01-01
                  相关资源
                  最近更新 更多