-2

SOで、探していることをほとんど実行する非常に優れた小さなスクリプトを見つけました。単語のリストの各出現箇所をウィキペディアへのリンクに置き換えます。問題は、最初の出現のみをリンクしたいということです。

これがスクリプトです(この回答から):

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を使用するように変更しようとしました(この回答から)、これは正規表現よりも速いと思います:

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
}

だから私の質問は、これら2つを組み合わせて、ライブラリを使用せずに最も効率的/最速の結果を得るにはどうすればよいですか?

4

1 に答える 1

1

これがあなたが望むことをするために修正されたあなたのコードです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;
    });
});​
于 2012-04-14T19:48:45.613 に答える