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

目标:

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

<code> ... </code>

与:

<pre> ... </pre>

My solution:

我已经说了很多了,

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

我的解决方案的问题是:

but the issues is that it's replacing everything between the (second, third, fourth, etc)"code" tags with the content between the 第一 "code" tags.

e.g.

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

变成了

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

我认为我需要使用“ this”和某种函数,但是我恐怕还在学习,不能真正理解如何拼凑一个解决方案。

82006 次浏览

你可以把一个函数传递给 .replaceWith < em > < sup > [ docs ] :

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

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

演示

更新: 性能差别不大,但是如果 code元素有其他 HTML 子元素,那么添加子元素而不是序列化它们感觉更正确:

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

您将始终获得第一个 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.
});

Try this:

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


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


});

Http://jsfiddle.net/mtghv/

这个怎么样?

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

这样好多了:

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

尽管不可否认 Felix Kling's solution大约是 两倍的速度:

从 jQuery 1.4.2开始:

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

然后您可以选择新的元素:

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

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

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

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

Best and clean way.

Building up on Felix's answer.

$('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标记的属性。

Edit: This will replace even those code tags that are inside the innerHTML of other code tags.

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

如果你使用的是普通的 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的解决方案都是 destructive

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

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

这可以处理任何一组需要交换的 html 元素标记,同时保留前一个标记的所有属性。

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

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

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

另一种简单快捷的方法:

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