jQuery用html替换匹配的文本 [英] jquery replace matching text with html

查看:97
本文介绍了jQuery用html替换匹配的文本的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想使用jQuery动态地将与给定正则表达式匹配的所有文本括入特定标签.例如:

<div class="content">
<div class="spamcontainer">
Eggs and spam is better than ham and spam.
<img src="spam-and-eggs.jpg">
I do not like green eggs and spam, though.
</div>
</div>

如果我的正则表达式为ham|spam,并且我想用<span class='meat-product'>括起来,那么我想转换为

<div class="content">
<div class="spamcontainer">
Eggs and <span class='meat-product'>spam</span> is better than <span class='meat-product'>ham</span> and <span class='meat-product'>spam</span>.
<img src="spam-and-eggs.jpg">
I do not like green eggs and <span class='meat-product'>spam</span>, though.
</div>
</div>

这是我的问题.我知道如何仅使用文本和仅使用html来做到这一点:

$("div.content").text(function() {
    return $(this).text().replace(/ham|spam/, function(match) {
        return '<span class="meat-product">' + match + '</span>';
        });
});

$("div.content").html(function(_, html) {
    return html.replace(/ham|spam/, function(match) {
        return '<span class="meat-product">' + match + '</span>';
        });
});

,但是前者将文本替换为文本(因此我得到了文本<span ...而不是<span>元素),而后者则在任何HTML而不是仅文本中都匹配了hamspam. >

我如何只匹配文本,还可以用HTML元素替换文本?

解决方案

我如何只匹配文本,还可以用HTML元素替换文本?

您可以选择所有后代元素和文本节点,并将集合过滤为仅包括文本节点.然后,您可以简单地将每个文本节点替换为修改后的字符串:

$(".content *").contents().filter(function() {
  return this.nodeType === 3;
}).replaceWith(function () {
  return this.textContent.replace(/(ham|spam)/g, '<span class="meat-product">$1</span>');
});

 $(".content *").contents().filter(function() {
  return this.nodeType === 3;
}).replaceWith(function() {
  return this.textContent.replace(/(ham|spam)/g, '<span class="meat-product">$1</span>');
}); 

 .meat-product {
  color: #f00;
} 

 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="content">
  <div class="spamcontainer">
    Eggs and spam is better than ham and spam.
    <img src="spam-and-eggs.jpg">I do not like green eggs and spam, though.
  </div>
</div> 

  • 使用通用选择器*选择所有后代元素(当然您也可以使用$('.content').children(),但这只会深入一层……您可能会遇到嵌套元素,这意味着您将需要检索 all 文本节点,因此我使用*选择所有后代元素的内容.
  • .contents()方法获取所有文本节点和子元素.
  • 然后过滤集合,以便仅包含文本节点,因为我们不想替换任何HTML.文本节点的nodeType属性值为3.
  • 最后, .replaceWith()方法用于用替换后的文本字符串更新每个文本节点. .replaceWith()方法的好处是,您可以用HTML字符串替换文本.
  • 您也可以使用捕获组来缩短.replace()方法,如上例所示.然后,您可以在span元素之间简单地替换$1.

I want to use jQuery to dynamically enclose all text matching a given regexp with a specific tag. For example:

<div class="content">
<div class="spamcontainer">
Eggs and spam is better than ham and spam.
<img src="spam-and-eggs.jpg">
I do not like green eggs and spam, though.
</div>
</div>

If my regexp is ham|spam and I want to enclose with <span class='meat-product'> then I would want to transform to

<div class="content">
<div class="spamcontainer">
Eggs and <span class='meat-product'>spam</span> is better than <span class='meat-product'>ham</span> and <span class='meat-product'>spam</span>.
<img src="spam-and-eggs.jpg">
I do not like green eggs and <span class='meat-product'>spam</span>, though.
</div>
</div>

Here's my problem. I know how to do this with just text, and with just html:

$("div.content").text(function() {
    return $(this).text().replace(/ham|spam/, function(match) {
        return '<span class="meat-product">' + match + '</span>';
        });
});

and

$("div.content").html(function(_, html) {
    return html.replace(/ham|spam/, function(match) {
        return '<span class="meat-product">' + match + '</span>';
        });
});

but the former replaces text with text (so I get the text <span ... instead of a <span> element), and the latter matches ham and spam inside any HTML rather than in just text.

How can I match only text, but also be able to replace that text with HTML elements?

解决方案

How can I match only text, but also be able to replace that text with HTML elements?

You could select all the descendant elements and text nodes and filter the set to only include text nodes. Then you can simply replace each text node with the modified string:

$(".content *").contents().filter(function() {
  return this.nodeType === 3;
}).replaceWith(function () {
  return this.textContent.replace(/(ham|spam)/g, '<span class="meat-product">$1</span>');
});

$(".content *").contents().filter(function() {
  return this.nodeType === 3;
}).replaceWith(function() {
  return this.textContent.replace(/(ham|spam)/g, '<span class="meat-product">$1</span>');
});

.meat-product {
  color: #f00;
}

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="content">
  <div class="spamcontainer">
    Eggs and spam is better than ham and spam.
    <img src="spam-and-eggs.jpg">I do not like green eggs and spam, though.
  </div>
</div>

  • Use the universal selector, *, to select all descendant elements (of course you could also use $('.content').children(), but that will only go one level deep... you will probably encounter nested elements which means that you will need to retrieve all text nodes, therefore I used * to select the contents of all the descendant elements).
  • The .contents() method gets all the text nodes and children elements.
  • Then filter the set so that only text nodes are included since we don't want to replace any HTML. The nodeType property value of a text node is 3.
  • Finally, the .replaceWith() method is used to update each text node with the replaced text string. The good thing about the .replaceWith() method is that you can replace the text with an HTML string.
  • You can also shorten your .replace() method by using a capturing group like in the example above. Then you can simply substitute $1 between the span elements.

这篇关于jQuery用html替换匹配的文本的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆