搜索词汇,用链接替换

4
我有一个这样的数组
var words = [
    {
        word: 'Something',
        link: 'http://www.something.com'
    },
    {
        word: 'Something Else',
        link: 'http://www.something.com/else'
    }
];

我希望它能够搜索页面上的单词并将其替换为链接。有没有有效的方法可以做到这一点?似乎可能会占用大量CPU资源。
抱歉,应该解释得更多一些......
例如,它会搜索每个具有类.message的元素。然后找到该类中的所有单词并将其替换为链接。
这个数组中也会有几百个。

我建议将其移动到服务器端。 - LiraNuna
1
嗯...CPU占用高了?只是简单的文本替换吗?同时,您需要提供有关该页面的更多背景信息,包括您正在处理哪些元素、结构等等。您知道的,通常情况下要提供这些信息。 - meder omuraliev
@LiraNuna:不幸的是,无法。@meder:添加了更多信息。 - Ben Shelock
唯一可靠的方法是遍历目标节点中的所有文本节点,并从那里进行替换。 - James
你想要一个实际的<a>标签吗? - Gutzofter
4个回答

3
一个好的策略是:
1)建立一个对象,其键是要替换的短语,其值是替换它们的链接。
2)在执行此操作时,构建一个可以匹配任何键的正则表达式,然后
3)使用该正则表达式进行全局替换。
粗略示例:
var replacementDict = {
    'foo': 'http://www.foo.com/',
    'bar': 'http://www.bar.net/'
};
var theRegex = /\b(foo|bar)\b/g;
theText.replace(theRegex, function(s, theWord) {
    return "<a href='" + replacementDict[theWord] + "'>" + theWord + "</a>";
});

3

假设有以下内容:

    <div class="message">Somethsg1</div>
    <div class="message">Something</div>
    <div class="message">Ssething</div>
    <div class="message">Something Else</div>
    <div class="message">Something da</div>
    <div class="message">Somethin2g</div>

你可以使用以下方式:
//your array
var words = [
    {
        word: 'Something',
        link: 'http://www.something.com'
    },
    {
        word: 'Something Else',
        link: 'http://www.something.com/else'
    }
];
//iterate the array
$.each(words,
    function() {
        //find an element with class "message" that contains "word" (from array)
        $('.message:contains("' + this.word + '")')
             //substitute html with a nice anchor tag
             .html('<a href="' + this.link + '">' + this.link + '</a>');
    }
);

但是,这种解决方案存在一个立即的问题(也在示例中显示)。如果您搜索 Something ,并找到 Something beautiful ,则“包含”将匹配。
如果您想进行严格选择,则必须执行:

//for each array element
$.each(words,
    function() {
        //store it ("this" is gonna become the dom element in the next function)
        var search = this;
        $('.message').each(
            function() {
                //if it's exactly the same
                if ($(this).text() === search.word) {
                    //do your magic tricks
                    $(this).html('<a href="' + search.link + '">' + search.link + '</a>');
                }
            }
        );
    }
);

你可以选择先迭代所有的数组元素,然后再迭代所有的dom元素;或者反过来。这也取决于你要搜索哪种类型的“单词”(请参见下面的两个示例,以了解原因)。

重要警告:如果数组包含用户定义的内容,则必须在将其注入到元素的HTML之前对其进行清理!


1

可以使用类似以下的方式实现:

$('*:contains("string to find")');

这种方法的问题在于"*"会返回包含字符串的所有元素,包括HTML、BODY等等...之后仍然需要在每个元素的文本节点中查找字符串,所以直接检查每个文本节点可能更容易...

我建议您看一下高亮插件,它已经做了与您想要的非常相似的事情(而不是链接,它会突出显示页面上的任何文本),但从源代码来看,它似乎很容易改变。


1
如果您想用'a'标签包装,请取消代码注释并注释上面的调用。 尝试这个:
var words = [
{
    word: 'Something',
    link: 'http://www.something.com'
},
{
    word: 'Something Else',
    link: 'http://www.something.com/else'
}];

var changeWordsWithLink = function (words) {
if(document.getElementById && document.getElementsByTagName) {
    var messages = document.getElementById('message');

    if(messages) {
        for(i = 0; i < messages.length; i++){
            for (j = 0; j < words.length; j++) {
                if(words[j].word == messages[i].innerHTML) {
                    messages[i].innerHTML = words[j].link;
                    //messages[i].innerHTML = wrapInATag(words[j].link, words[j].word);
                }
            }
        }
    }
}
}

var wrapInATag = function(link, word) {
   return '<a href="' + link + '">' + word + '</a>';
}

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