jQuery:查找文本并替换为HTML

8
我尝试查找并替换文本(使用jQuery)。 实际上,我正在尝试在文本周围添加span元素。我还应该能够删除span,而不会丢失其中的文本。
例如,假设我从以下情况开始:
<span>This is a span element</span>

我希望能够使用jQuery/JavaScript动态地实现以下功能:

<span>This is a <span class="marked">span</span> element</span>

我还应该能够删除 span.marked 并返回第一个结果。

然而问题是,我想对一个包含多个子元素和子子元素的容器中的所有文本进行操作。

到目前为止,我得到的代码将执行以下操作,但这不是我想要的:

<<span class="marked">span</span>>This is a <span class="marked">span</<span class="marked">span</span> element</span>

我希望您能将此应用于页面上所有文本,而不仅仅是第一个找到的文本。
编辑:我目前为此编写的代码:
var re = new RegExp(word, 'g');
$('.container').html($('.container').html().replace(re, '<span class="marked">' + word + '</span>'));

word是一个包含要用span标签包裹的文本的字符串。


6
展示你的JS代码。 - Satpal
2
在你的最后一行代码中,我看到了双重 << 和 >> 围绕着你的第一个 span="marked"。这是一个类型错误还是...? - Mivaweb
2
你可以在搜索“span”单词时在前后加上空格,以免替换掉你的 span 元素。 - Straw Hat
2
@VDesign 这就是他遇到的问题。他的代码将“span”包裹在现有的<span>标签内,使用<span class="marked">.... - Andy
我有一个可行的解决方案。请看下面我的答案。 - PeterKA
7个回答

11

要将搜索字符串用HTML包装,可以使用类似以下的代码:

$('span:contains("word")').html().replace('word', '<span class="marked">word</span>');

要删除它,您可以使用类似于此的代码:

$('span:contains("word")').html().replace('<span class="marked">word</span>', 'word');

是的,这种方式比较粗糙,但它应该可行。

编辑: 如@user3558931所指出的,单词需要是一个变量。

要将搜索字符串包装在html中,您可以使用类似以下内容的东西:

$('span:contains("' + str + '")').html().replace(str, '<span class="marked">' + str + '</span>');

如果要删除它,您可以使用类似以下的内容:

$('span:contains("' + str + '")').html().replace('<span class="marked">' + str + '</span>', str);

编辑:上述代码中存在一个故障,请查看此fiddle中的修复代码:http://jsfiddle.net/thePav/7TNk6/21/


1
这样做不行。根据PO,“word”是一个变量,而不是一个字符串。 - PeterKA
抱歉,我会更新代码的。我想原始问题在我回答之后被更新了。 - PavKR
1
这只适用于 span 标签吗?我想对容器内的所有嵌套标签都这样做。我尝试了您的代码,如 $('*:contains(.... 但似乎没有起作用。 - Wouter
是的,那段代码是针对 span 标签的。如果要使用选择器类来实现这个功能,你可以使用类似于 $('.container').html() 的代码。 - PavKR
抱歉,那段代码出了一些问题。首先,您需要将数据存储到变量中,然后再应用它。请查看此fiddle:http://jsfiddle.net/thePav/7TNk6/21/。 - PavKR
只需编辑答案中的代码即可,不要让人们去其他网站寻找答案... - Heretic Monkey

6
$('.container p').each(function() {
    var text = $(this).text();
    $(this).html(text.replace('word', '<strong><span class="accordion">word </span></strong>')); 
});

2
不要使用正则表达式。使用DOM遍历,这将更可靠、更快速,也不会造成破坏(例如,事件处理程序不会被破坏)。
请参见https://stackoverflow.com/a/10618517/96100,其中有一个简单的示例。
或者,您可以使用以下方法:

http://james.padolsey.com/javascript/replacing-text-in-the-dom-solved/

这并未涵盖之后删除跨度的内容,但这是一个相当简单的问题。类似以下代码(未经测试):
function replaceWithOwnChildren(el){
    var parent = el.parentNode;
    while (el.hasChildNodes()) {
        parent.insertBefore(el.firstChild, el);
    }
    parent.removeChild(el);
}

// Create a non-live standard array of spans
var spans = [].slice.call(document.getElementsByTagName("span"), 0);
for (var i = 0, len = spans.length; i < len; ++i) {
    if (spans[i].className == "marked") {
        replaceWithOwnChildren(spans[i]);
    }
}

// Glue together any adjacent text nodes
document.normalize();

1
我认为需要调整正则表达式,以便它不会选择任何HTML标签,比如 <span。我想建议以下正则表达式:
var re = new RegExp('[^<\\/](' + word + ')', 'g');

而且替换:

$('.container').each(function() {
    $(this).html( $(this).html().replace( re, ' <span class="marked">$1</span>' ) );
});

使用以下演示中的代码(单击按钮)可以将其反转:

$('button.undo').on( 'click', function() {
    $('.container').find( 'span.marked' ).each(function() {
        $(this).replaceWith( word );
    });
});

JS FIDDLE DEMO

其他 DEMO


1
var mark = function(word){
    return function(){
        this.innerHTML = this.innerHTML.replace(word,'' + word + '');
    }
};
$('span').each(mark('span'));
意思是定义了一个函数mark,它接收一个参数word,返回一个函数。这个返回的函数会将它所在的元素的innerHTML中所有出现的word替换成'' + word + ''。
然后用jQuery的each方法遍历所有的标签,并对每个标签调用mark函数,传入参数'span'。

我的HTML代码有点复杂:http://jsfiddle.net/TCvg7/2/ <-- 这只是一个例子,实际版本还有更多的标签和嵌套标签。 - Wouter

0

尝试使用以下内容:

$('.container').forEach(function(){ 
    $(this).html().... 
})

如果这是你的问题,那就好办了。否则,请澄清一下,到底哪里出了问题?


0
var span = document.getElementsByTagName("span")[0];
span.innerHTML = span.innerHTML.replace(/span/g, "<span class=\"marked\">span</span>");

http://jsfiddle.net/7TNk6/1/


不仅仅是 span 元素,我想要修改整个页面。就像这样:http://jsfiddle.net/7TNk6/3/ - Wouter
好的,看起来你已经从我的解决方案中得出了自己的解决方案。那么你的解决方案有什么问题吗? - ndugger
它也可以替换HTML标签。但它只应该替换HTML标签中的文本。 - Wouter
尝试这个简单的修复:http://jsfiddle.net/7TNk6/17/ 我所做的就是在替换词前面添加一个空格,在替换它的HTML中也一样。虽然不太优雅,但却起作用了。 - ndugger
当我需要标记元素的第一个单词时,这会带来问题。但它已经接近我所需的了。 - Wouter

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接