使用 jQuery 将一个标签替换为另一个标签

Posted

技术标签:

【中文标题】使用 jQuery 将一个标签替换为另一个标签【英文标题】:Using jQuery to replace one tag with another 【发布时间】: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 - 看看 ;) 【参考方案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();

【讨论】:

以上是关于使用 jQuery 将一个标签替换为另一个标签的主要内容,如果未能解决你的问题,请参考以下文章

jQuery:向下滑动并以特殊方式将一个背景图像替换为另一个背景图像

用 html/jquery 中的一个 JSON 字符串替换许多数据标签 [重复]

JQuery 根据另一个字段的值替换选择选项标签

如何使用 JQuery 在不移动页面的情况下将 div 的整个视图替换为另一个 div

jquery点击替换为另一个图像

jquery用变量替换标签名称