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


100

目标:

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

<code> ... </code>

与:

<pre> ... </pre>

我的解决方案:

我了解到以下内容:

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

我的解决方案的问题:

但是问题在于它用第一个 “ code”标签之间的内容替换了(第二,第三,第四等)“ code”标签之间的所有内容。

例如

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

变成

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

我认为我需要使用“ this”和某种功能,但恐怕我还在学习,并且不太了解如何将解决方案组合在一起。


修复了现在可以自动打包的解决方案;请检查一下;)
Jens Roland

Answers:


157

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

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

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

演示

更新:没有很大的性能差异,但是如果code元素具有其他HTML子代,则添加子代而不是对其进行序列化会更正确:

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

1
这似乎是最优雅的解决方案,但是我承认我不明白replaceWith函数内部发生了什么。希望听到更多。即如何分配开始和结束标签?<pre />中的空格能做到这一点吗?
乔恩·

2
@jon:这是创建新元素的捷径。可以在这里找到更多信息:api.jquery.com/jQuery/#jQuery2。jQuery遍历所有元素并为每个元素执行功能(相同操作.each)。
Felix Kling

@jon:但是请再次检查Jens的解决方案,他已将其修复。
菲利克斯·克林

1
+1是个不错的窍门-除了简单的标签替换外,它还可以用于更多的用途。
詹斯·罗兰

@FelixKling这不会覆盖代码标签的属性吗?
tewathia,2013年

80

这样好得多:

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

尽管公认的是Felix Kling的解决方案速度大约是以前的两倍


4
就像魅力一样,在我看来,这似乎是最有效的解决方案。:)
乔恩·

啊哈 是的,你们是对的。这对我也不起作用。感谢您抓住这一点!
乔恩

1
FWIW,$('code').children()将为上述示例返回一个空的jQuery对象,因为这些code元素没有子元素节点。虽然它的工作原理,如果有子元素。
Felix Kling

1
固定-正确,当内容由单个文本节点组成时,children()将不起作用。contents()相反,使用效果很好。jsfiddle.net/7Yne9
詹斯·罗兰

1
这是一个不会破坏页面的jsperf版本:jsperf.com/substituting-one-tag-for-another-with-jquery/2,您会发现速度差异不再那么大了。解决方案的速度较慢,因为每个元素执行两个DOM操作:unwrap删除父级并将子级添加到树中,wrap再次分离它们并添加新的父级。
菲利克斯·克林

26

始终获得first 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.
});

12

试试这个:

$('code').each(function(){

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

});

http://jsfiddle.net/mTGhV/


哇。你们在彼此之间2秒钟之内提出了完全相同的解决方案。格式上的差异很小。我不确定要投票的是哪一个-我真的不喜欢托马斯回答中的函数和()之间的空格,而kokos回答中的两行空白很漂亮,并且()之间应该有空格和{
Michael Bylstra

11

这个怎么样?

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

6

建立在费利克斯的答案上。

$('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;
});

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

编辑:这将取代甚至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');

2
到目前为止最好的答案。其他的几乎都是一样的,人们投票支持他们真的很奇怪。祝贺您是唯一考虑过属性的人。
Guilherme David da Costa


2

如果您使用的是原始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具有破坏性的解决方案。



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

最好的清洁方式。


0

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

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

这可以与需要交换的任何一组html元素标签一起使用,同时保留先前标签的所有属性。


0

制作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')

0

此处给出的所有答案均假设(如问题示例所示)标签中没有属性。如果对此接受了答案:

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

如果将被替换

<pre>A</pre>

如果您还想保留属性,该怎么办-替换标签将意味着...?这是解决方案:

$("code").each( function(){
    var content = $( "<pre>" );

    $.each( this.attributes, function(){ 
         content.attr( this.name, this.value );
    } );

    $( this ).replaceWith( content );
} );

我知道这已经有两年了,但我只是想提一提...您忘记了保留上一个元素中的html。在您的代码段中,您只是使用属性创建了一个新元素,而没有复制任何子元素。
朋友

可以通过添加content.html( this.html )
帕特里克
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.