【问题标题】:Using jQuery to replace one tag with another使用 jQuery 将一个标签替换为另一个标签
【发布时间】:2011-10-28 22:27:15
【问题描述】:

目标:

使用 jQuery,我试图替换所有出现的:

<code> ... </code>

与:

<pre> ... </pre>

我的解决方案:

我得到了以下,

$('code').replaceWith( "<pre>" + $('code').html() + "</pre>" );

我的解决方案的问题:

但问题是它正在用 first “code”标签之间的内容替换(第二、第三、第四等)“code”标签之间的所有内容。

例如

<code> A </code>
<code> B </code>
<code> C </code>

变成

<pre> A </pre>
<pre> A </pre>
<pre> A </pre>

我认为我需要使用“this”和某种功能,但恐怕我仍在学习,并不真正了解如何将解决方案拼凑在一起。

【问题讨论】:

  • 现在修复了 wrap-unwrap 解决方案 jon - 看看 ;)

标签: javascript jquery replace


【解决方案1】:

您可以将函数传递给.replaceWith [docs]:

$('code').replaceWith(function(){
    return $("<pre />", {html: $(this).html()});
});

在函数内部,this指的是当前处理的code元素。

DEMO

更新:有no big performance difference,但如果code元素有其他HTML子元素,附加子元素而不是序列化它们感觉更正确:

$('code').replaceWith(function(){
    return $("<pre />").append($(this).contents());
});

【讨论】:

  • 这似乎是最优雅的解决方案,但我承认我不明白 replaceWith 函数内部发生了什么。很想听到更多。即如何分配开始和结束标签?
     中的空间能做到这一点吗?
  • @jon:它是创建新元素的简写。更多信息可以在这里找到:api.jquery.com/jQuery/#jQuery2。 jQuery 循环遍历所有元素并为每个元素执行函数(与 .each 所做的相同)。
  • @jon:但是再次检查 Jens 的解决方案,他修复了它。
  • +1 是一个不错的技巧 - 这不仅可以用于简单的标签替换。
  • @FelixKling 这不会覆盖代码标签的属性吗?
【解决方案2】:

您总是会获得第一个code 的内容是正确的,因为$('code').html() 将始终引用第一个元素,无论您在哪里使用它。

相反,您可以使用.each 迭代所有元素并单独更改每个元素:

$('code').each(function() {
    $(this).replaceWith( "<pre>" + $(this).html() + "</pre>" );
    // this function is executed for all 'code' elements, and
    // 'this' refers to one element from the set of all 'code'
    // elements each time it is called.
});

【讨论】:

    【解决方案3】:

    试试这个:

    $('code').each(function(){
    
        $(this).replaceWith( "<pre>" + $(this).html() + "</pre>" );
    
    });
    

    http://jsfiddle.net/mTGhV/

    【讨论】:

    • 哇。你们在 2 秒内提出了完全相同的解决方案。有微小的格式差异。我不确定要支持哪一个 - 我真的不喜欢 thomas 答案中函数和 () 之间的空格,而 kokos 答案中的 2 行空白非常有意义 + () 之间应该有一个空格和 {
    【解决方案4】:

    这个怎么样?

    $('code').each(function () {
        $(this).replaceWith( "<pre>" + $(this).html() + "</pre>" );
    });
    

    【讨论】:

      【解决方案5】:

      这样更好:

      $('code').contents().unwrap().wrap('<pre/>');
      

      虽然不可否认Felix Kling's solution 大约是twice as fast:

      【讨论】:

      • 就像一个魅力,在我的外行看来,这似乎是最有效的解决方案。 :)
      • 啊哈。是的,你们是对的。它也对我不起作用。谢谢你接听!
      • FWIW, $('code').children() 将为上面的示例返回一个空的 jQuery 对象,因为 code 元素没有子元素节点。虽然 if 可以工作,但有子元素。
      • 已修复 - true,当内容由单个文本节点组成时,children() 将不起作用。使用 contents() 可以完美地工作。 jsfiddle.net/7Yne9
      • 这是一个不会破坏页面的 jsperf 版本:jsperf.com/substituting-one-tag-for-another-with-jquery/2,您会发现速度差异不再那么大了。您的解决方案较慢,因为您对每个元素执行两次 DOM 操作:unwrap 删除父级并将子级添加到树中,wrap 再次分离它们并添加新父级。
      【解决方案6】:

      从 jQuery 1.4.2 开始:

      $('code').replaceWith(function(i,html) {
        return $('<pre />').html(html);
      });​
      

      然后您可以选择新元素:

      $('pre').css('color','red');
      

      来源:http://api.jquery.com/replaceWith/#comment-45493689

      jsFiddle:http://jsfiddle.net/k2swf/16/

      【讨论】:

        【解决方案7】:
        $('code').each(function(){
            $(this).replaceWith( "<pre>" + $(this).html()  + "</pre>" );
            });
        

        最好和干净的方式。

        【讨论】:

          【解决方案8】:

          以 Felix 的回答为基础。

          $('code').replaceWith(function() {
              var replacement = $('<pre>').html($(this).html());
              for (var i = 0; i < this.attributes.length; i++) {
                  replacement.attr(this.attributes[i].name, this.attributes[i].value);
              }
              return replacement;
          });
          

          这将在替换pre标签中重现code标签的属性。

          编辑:这将替换其他 code 标签的 innerHTML 内的 code 标签。

          function replace(thisWith, that) {
              $(thisWith).replaceWith(function() {
                  var replacement = $('<' + that + '>').html($(this).html());
                  for (var i = 0; i < this.attributes.length; i++) {
                      replacement.attr(this.attributes[i].name, this.attributes[i].value);
                  }
                  return replacement;
              });
              if ($(thisWith).length>0) {
                  replace(thisWith, that);
              }
          }
          
          replace('code','pre');
          

          【讨论】:

          • 迄今为止的最佳答案。其他的几乎都是一样的,这真的很奇怪,人们支持它们。恭喜你成为唯一一个考虑过属性的人。
          【解决方案9】:

          如果您使用的是原生 JavaScript,您会:

          • 创建新元素
          • 将旧元素的子元素移动到新元素中
          • 在旧元素之前插入新元素
          • 移除旧元素

          这里是这个过程的 jQuery 等价物:

          $("code").each(function () {
              $("<pre></pre>").append(this.childNodes).insertBefore(this);
              $(this).remove();
          });
          

          这里是 jsperf 网址:
          http://jsperf.com/substituting-one-tag-for-another-with-jquery/7

          PS:所有使用.html() 或.innerHTML 的解决方案都是破坏性。

          【讨论】:

            【解决方案10】:

            你可以使用 jQuery 的 html 函数。下面是一个示例,它用 pre 标记替换了代码标记,同时保留了代码的所有属性。

                $('code').each(function() {
                    var temp=$(this).html();
                    temp=temp.replace("code","pre");
                    $(this).html(temp);
                });
            

            这适用于任何需要交换的 html 元素标签集,同时保留前一个标签的所有属性。

            【讨论】:

              【解决方案11】:

              制作jquery插件,同时维护属性。

              $.fn.renameTag = function(replaceWithTag){
                this.each(function(){
                      var outerHtml = this.outerHTML;
                      var tagName = $(this).prop("tagName");
                      var regexStart = new RegExp("^<"+tagName,"i");
                      var regexEnd = new RegExp("</"+tagName+">$","i")
                      outerHtml = outerHtml.replace(regexStart,"<"+replaceWithTag)
                      outerHtml = outerHtml.replace(regexEnd,"</"+replaceWithTag+">");
                      $(this).replaceWith(outerHtml);
                  });
                  return this;
              }
              

              用法:

              $('code').renameTag('pre')
              

              【讨论】:

                【解决方案12】:

                这里给出的所有答案都假设(如问题示例所示)标签中没有属性。如果接受的答案在此运行:

                <code class='cls'>A</code>
                

                if 将被替换为

                <pre>A</pre>
                

                如果您还想保留属性怎么办 - 这就是替换标签的意思...?这是解决方案:

                $("code").each( function(){
                    var content = $( "<pre>" );
                
                    $.each( this.attributes, function(){ 
                         content.attr( this.name, this.value );
                    } );
                
                    $( this ).replaceWith( content );
                } );
                

                【讨论】:

                • 我知道这是几年前的事了,但我只是想提一下……你忘了保留前一个元素的 html。在您的代码 sn-p 中,您只是创建了一个具有属性的新元素,而没有复制任何子元素。
                • 这将通过添加content.html( this.html )来完成
                【解决方案13】:

                另一种简单的方法:

                $('code').wrapInner('<pre />').contents();
                

                【讨论】:

                  猜你喜欢
                  • 2015-06-24
                  • 2015-12-22
                  • 2013-11-23
                  • 2013-04-23
                  • 1970-01-01
                  • 2015-09-19
                  • 1970-01-01
                  • 1970-01-01
                  相关资源
                  最近更新 更多