找到特定的单词并用<span>标签包裹起来

4

我不确定如何最好地解决这个问题。问题是这样的:我有一个菜单(列表项),它具有不规则的显示模式。由于它是从 CMS 中输出的,所以我不能直接更改 HTML。如果数组中的单词与链接中的单词匹配,则希望将该单词用 span 标签包裹起来。

以下是简化后的代码:

<li class="item1"><a href="gosomewhere.html">About My Store</a></li>
<li class="item2"><a href="gosomewhereelse.html">Find Locations</a></li>

result i want is this:

<li class="item1"><a href="gosomewhere.html"><span class="bigwords">About My </span>Store</a></li>
<li class="item2"><a href="gosomewhere.html">Find <span class="bigwords">Locations</span></a></li>

我可以通过以下方法找到第一个单词:
      $(function() {
    $.fn.wrapStart = function (numWords) {
    var node = this.contents().filter(function () { return this.nodeType == 3 }).first(),
        text = node.text(),
        first = text.split(" ", numWords).join(" ");

    if (!node.length)
        return;

    node[0].nodeValue = text.slice(first.length);
    node.before('<span class="bigwords">' + first + '</span>');
};


$("li.item1 a").wrapStart(1);

然而,我想要做的是浏览一个数组列表并将我想要的特定单词包装在它们出现的任何位置。
该数组可能是这样的:about,store,faq...
脚本会查找这些单词并将它们包装起来...
不太确定如何去做。如果更容易的话,由于这些大单词只出现在开头或结尾而不在中间... 我可以编写另一个函数来查找最后一个单词。
只有5个菜单项(不会改变),而且单词永远不会改变,这就是为什么我考虑使用一个数组的原因...
以下是插件使用时的输出结果:
<ul class="menu><li class="item-102 parent">
<a class="about" title="About my store" href="#">
<span class="bigwords">
<a xmlns="http://www.w3.org/1999/xhtml">About</a>
</span>
<a xmlns="http://www.w3.org/1999/xhtml"> my store</a>
</a>
</li></ul>
3个回答

4
我最近写了一个简单的插件,可以完成这个功能:

(它已经不再存在了)

你可以像这样使用它:

var arr = ["about my","locations"];
$.each(arr,function(i,word){
  $(".items").highlightText(word,"bigwords",true)
});

http://jsfiddle.net/4gtmH/23/

由于我使用正则表达式,您也可以这样做:

$(".items").highlightText("about my|locations","bigwords",true)

同时:

我使用.items作为类名是因为在我的示例中,我给ul元素添加了一个items类。您可以提供任何选择器,它将突出显示元素及其子元素中的所有文本。

以下是插件执行工作的部分,以防那个链接出现问题:

$(this).find("*").andSelf().contents()

// filter to only text nodes that aren't already highlighted
.filter(function () {
    return this.nodeType === 3 && $(this).closest("." + hClass).length === 0;
})

// loop through each text node
.each(function () {
    var output;
    output = this.nodeValue.replace(re, "<" + defaultTagName + " class='" + hClass + "'>$1</" + defaultTagName + ">");
    if (output !== this.nodeValue) {
        $(this).wrap("<p></p>").parent()
            .html(output).contents().unwrap();
    }
});

什么浏览器?我在Chrome中没有看到额外的锚点标签。而且,在IE中似乎也无法正常工作。 - Kevin B
是的,在 FF 和 JSFiddle 上都会出现这种情况。它似乎会导致元素的样式问题... 我会在我的帖子中添加代码... - liz
嗯...我以前见过这个问题,但是我忘记是什么原因引起的了...你使用的文档类型是什么? - Kevin B
一个快速解决额外a标签问题的方法是 $(".menu").find("a[xmlns]").children().unwrap(),但如果可能的话,我想能够在插件内部防止它。此外,我在Firefox 6中没有看到这种行为。 - Kevin B
这是关于这个问题的一篇文章,我会尽快将其实现到插件中。https://dev59.com/2lDTa4cB1Zd3GeqPKIsP - Kevin B
显示剩余5条评论

0

你看过这个jQuery插件吗?我自己没用过,但看起来很容易完成工作。


0

您可以在所有元素上进行jQuery选择器,并对选择器中的每个结果设置val,将val替换为数据


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