在jQuery中查找文本字符串并加粗显示

31

我想使用jQuery在段落中查找一段文本并添加CSS使其加粗。但我似乎无法弄清楚为什么下面的代码不起作用:

$(window).load(function() {
// ADD BOLD ELEMENTS
$('#about_theresidency:contains("cross genre")').css({'font-weight':'bold'});
});

“about_theresidency”中的文本是动态获取的,因此在窗口加载后我执行它。


2
即使这样做可以在某种程度上起作用,它会使整个元素变粗体,但肯定不仅限于你的两个单词。CSS 只能应用于标签,而不能应用于文本。 - Sven Bieder
@Diodeus 我正在使用JSON将文本放入span标签中:<div class="content"> <h1>关于我们</h1> <span id="about_theresidency"></span> - Michael
我也尝试了:$('#about_theresidency:contains("cross genre")').wrap("<b></b>");但是没有成功。 - Michael
即使能够将类添加到文本中也可以,只是无法弄清如何选择那一部分文本。 - Michael
如果此代码位于$(window).load()中,那么拉取json字符串并设置内容的代码在哪里?我猜是在之后,这就是为什么它不起作用的原因。$(window).load()非常早。 - bhamlin
显示剩余3条评论
5个回答

89
你可以使用replace()html()方法:
var html = $('p').html();
$('p').html(html.replace(/world/gi, '<strong>$&</strong>'));

编辑: http://jsbin.com/AvUcElo/1/edit

我把它变成了一个小插件,这里:

$.fn.wrapInTag = function(opts) {

  var tag = opts.tag || 'strong'
    , words = opts.words || []
    , regex = RegExp(words.join('|'), 'gi') // case insensitive
    , replacement = '<'+ tag +'>$&</'+ tag +'>';

  return this.html(function() {
    return $(this).text().replace(regex, replacement);
  });
};

// Usage
$('p').wrapInTag({
  tag: 'em',
  words: ['world', 'red']
});

谢谢,伙计!这个方法很有效,我把它放在我的循环里面,结果就成功了! - Michael
不错的插件..但是如果有1000个不同的用引号括起来的单词,而且所有这些单词都需要被赋予红色类别怎么办?我们可能需要在'code'单词中添加正则表达式:[ 正则表达式在这里, 'red']正则表达式应该是什么? - Jigar Jain
我猜你可以用引号传递单词:words: ['"world"', '"red"'] - elclanrs
3
您的解决方案可行,但会破坏内部标签(如果在您更改的元素内部存在任何标签),因此我冒昧地进行了一些修改,并将其发布为另一种答案。 - jahu
提醒其他人,这在IE8中会失败并停止执行。 - red

16

我曾经遇到类似的问题,尝试使用elclanrs提出的解决方案。它很好用,但前提是您要修改的文本中没有任何HTML元素。如果文本中包含任何标签,则在运行wrapInTag函数后这些标签将会丢失。

下面是我的内部节点友好型解决方案(我还包含了编写代码所使用的资源链接)。

// https://dev59.com/zWkw5IYBdhLWcg3wlbd3#9795091
$.fn.wrapInTag = function (opts) {
    // https://dev59.com/kXI-5IYBdhLWcg3w18V3#1646618
    function getText(obj) {
        return obj.textContent ? obj.textContent : obj.innerText;
    }

    var tag = opts.tag || 'strong',
        words = opts.words || [],
        regex = RegExp(words.join('|'), 'gi'),
        replacement = '<' + tag + '>$&</' + tag + '>';

    // https://dev59.com/xnVC5IYBdhLWcg3wbgdS#298758
    $(this).contents().each(function () {
        if (this.nodeType === 3) //Node.TEXT_NODE
        {
            // https://dev59.com/WlzUa4cB1Zd3GeqPzArq#7698745
            $(this).replaceWith(getText(this).replace(regex, replacement));
        }
        else if (!opts.ignoreChildNodes) {
            $(this).wrapInTag(opts);
        }
    });
};

示例:http://jsbin.com/hawog/1/edit


你应该检查 this.nodeType == Node.TEXT_NODE 而不是检查 this.nodeType === 3 - Jason Axelson
1
@JasonAxelson 如https://dev59.com/xnVC5IYBdhLWcg3wbgdS#298758中所述,`this.nodeType == Node.TEXT_NODE在IE7中无法工作,但是this.nodeType === 3`在大多数浏览器中都可以工作。 - jahu
2
谢谢!这太棒了。我发现它可以匹配部分单词 - 所以如果你传入'word',它将匹配'word'和'sword'。我更新了正则表达式的这一行代码:regex = RegExp('(^|\\s)' + words.join('(\\s|$)|(^|\\s)') + '(\\s|$)', 'gi'),这将仅匹配由空格限定的完整单词。在我的情况下,我正在构建一个拼写检查器,因此我只需要高亮显示完整单词。 - Sean
@Sean 我需要这个来突出显示搜索结果,因此匹配部分单词是有意的。 - jahu
两种用例都是有效的,我认为 :) - Sean
为什么这个不适用于span标签?我使用了**replacement = '<span class="red">$&</span>'**代替标签变量,但它什么也没做。 - olop01

1

尝试:

$(window).load(function() {
// ADD BOLD ELEMENTS
    $('#about_theresidency:contains("cross genre")').each(function(){
        $(this).html( 
            $(this).html().replace(/cross genre/g,'<strong>$&</strong>')
        );
    });
});

用 @elclanrs 的代码终于搞定了,不管怎样还是感谢你的帮助,老兄! - Michael

0

我已经采用并调整了@jahu提供的代码,使其可以添加数据属性,然后在DOM上运行回调函数,以便在您的模板中存在像这样的代码:$('foo').wrapInTag(...)

<p data-js-highlight-text="hello,">
  <span style="color: #009fff">Hello,</span> World
</p>

// Extended examples with data attributes in your html:
//
// Set the data-js-highlight-text attribute. Before:

<p data-js-highlight-text="hello,">Hello, World</p>

// After:
<p data-js-highlight-text="hello,"><span style="color: #009fff">Hello,</span> World</p>


0

需要一种更安全的方法,可以进行转义。这里有一个基本解决方案。

var str = 'The world is big <b onclick="alert(false)">world</b> red. the world is also small'
var words = ['world', 'is']
var reg = RegExp(words.join('|'), 'gi')
var p = document.createElement('p')
p.innerText = str
p.innerHTML = p.innerHTML.replace(reg, '<u>$&</u>')

document.body.appendChild(p)
console.log(p.outerHTML)


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