用链接替换列表中每个单词的第一个出现
问题描述:
我发现了一个非常漂亮的小脚本,它几乎可以完成我正在寻找的任务。它用维基百科的链接替换每个单词列表的发生。问题是我只想要第一次发生联系。用链接替换列表中每个单词的第一个出现
这里是脚本(从this answer):
function replaceInElement(element, find, replace) {
// iterate over child nodes in reverse, as replacement may increase
// length of child node list.
for (var i= element.childNodes.length; i-->0;) {
var child= element.childNodes[i];
if (child.nodeType==1) { // ELEMENT_NODE
var tag= child.nodeName.toLowerCase();
if (tag!='style' && tag!='script') // special case, don't touch CDATA elements
replaceInElement(child, find, replace);
} else if (child.nodeType==3) { // TEXT_NODE
replaceInText(child, find, replace);
}
}
}
function replaceInText(text, find, replace) {
var match;
var matches= [];
while (match= find.exec(text.data))
matches.push(match);
for (var i= matches.length; i-->0;) {
match= matches[i];
text.splitText(match.index);
text.nextSibling.splitText(match[0].length);
text.parentNode.replaceChild(replace(match), text.nextSibling);
}
}
// keywords to match. This *must* be a 'g'lobal regexp or it'll fail bad
var find= /\b(keyword|whatever)\b/gi;
// replace matched strings with wiki links
replaceInElement(document.body, find, function(match) {
var link= document.createElement('a');
link.href= 'http://en.wikipedia.org/wiki/'+match[0];
link.appendChild(document.createTextNode(match[0]));
return link;
});
我一直在试图修改(没有成功)使用的indexOf insted的正则表达式(从this answer),我相信这将是比快正则表达式:
var words = ["keyword","whatever"];
var text = "Whatever, keywords are like so, whatever... Unrelated, I now know " +
"what it's like to be a tweenage girl. Go Edward.";
var matches = []; // An empty array to store results in.
//Text converted to lower case to allow case insensitive searchable.
var lowerCaseText = text.toLowerCase();
for (var i=0;i<words.length;i++) { //Loop through the `words` array
//indexOf returns -1 if no match is found
if (lowerCaseText.indexOf(words[i]) != -1)
matches.push(words[i]); //Add to the `matches` array
}
所以我的问题是如何结合这两个来获得最高效/最快的结果,而不使用库?
答
这里修改你的代码,做你想做http://jsfiddle.net/bW7LW/2/
function replaceInit(element, find, replace) {
var found = {},
replaceInElement = function(element, find, replace, init) {
var child, tag,
len = element.childNodes.length,
i = 0,
replaceInText = function(text, find, replace) {
var len = find.length,
index, i = 0;
for (; i < len; i++) {
index = text.data.indexOf(find[i]);
if (index !== -1 && found && !found[find[i]]) {
found[find[i]] = true;
text.splitText(index);
text.nextSibling.splitText(find[i]);
text.parentNode.replaceChild(replace(find[i]), text.nextSibling);
return;
};
};
};
// iterate over child nodes in reverse, as replacement may increase length of child node list.
for (; i < len; i++) {
child = element.childNodes[i];
if (child.nodeType == 1) { // ELEMENT_NODE
tag = child.nodeName.toLowerCase();
if (tag != 'style' && tag != 'script') {
replaceInElement(child, find, replace);
}
} else if (child.nodeType == 3) { // TEXT_NODE
replaceInText(child, find, replace);
}
}
};
replaceInElement(element, find, replace);
};
// keywords to match. This *must* be a 'g'lobal regexp or it'll fail bad
var find = 'Lorem Ipsum bla'.split(' ');
$(function() {
// replace matched strings with wiki links
replaceInit(document.body, find, function(str) {
var link = document.createElement('a');
link.href = 'http://en.wikipedia.org/wiki/' + str;
link.appendChild(document.createTextNode(str));
return link;
});
});
我看到什么都“的Lorem”被链接,而不是仅仅在第一 – ofko 2012-04-14 21:07:19
每一个元素,如何代码工作,但它只能更换第一份。它可以修改它,只需要跟踪哪些表达式被发现。 – GillesC 2012-04-14 21:09:25
http://jsfiddle.net/bW7LW/2/在这里这个工作,我不得不扭转元素的循环,否则它会从底部到顶部而不是从顶部到底部。 – GillesC 2012-04-14 21:30:48