0

dom 検索/置換スクリプトを変更して、それに一致する複数のキーワードをドキュメント内のリンクで置換しました。

<div>またはなしでうまく機能<p>していましたが、複雑な構造で各ノードのキーワードが置き換えられています...

これは例です

ご覧のとおり、要素内で同じキーワードが複数回リンクされているわけではありませんが、他の要素がいくつかある間にキーワードがリンクされています...

これがスクリプトです

(function(){
    // don't replace text within these tags
    var skipTags = { 'a': 1, 'style': 1, 'script': 1, 'iframe': 1, 'meta':1, 'title':1, 'img':1, 'h1':1 };
    // find text nodes to apply replFn to
    function findKW( el, term, replFn ) 
    {
        var child, tag;
        if(!found)var found=false;
        for (var i = 0;i<=el.childNodes.length - 1 && !found; i++)
        {
            child = el.childNodes[i];
            if (child.nodeType == 1) 
            { // ELEMENT_NODE
                tag = child.nodeName.toLowerCase();
                if (!(tag in skipTags)) 
                {
                    findKW(child, term, replFn);
                }
            } 
            else if (child.nodeType == 3) 
            { // TEXT_NODE
                found=replaceKW(child, term, replFn);
            }
        }
     };    
    // replace terms in text according to replFn
    function replaceKW( text, term, replFn) 
    {
        var match,
            matches = [],found=false;
        while (match = term.exec(text.data)) 
        {
            matches.push(match);
        }
        for (var i = 0;i<=matches.length - 1 && !found; i++)
        {           
            match = matches[i];            
            // cut out the text node to replace
            text.splitText(match.index);
            text.nextSibling.splitText(match[1].length);
            text.parentNode.replaceChild(replFn(match[1]), text.nextSibling);
            if(matches[i])found=true;// To stop the loop            
        }
        return found;
    };
    // Keywords to replace by a link
    var terms=Array('keywords','words');
    for(kw in terms)
    {
        findKW(
            document.body, 
            new RegExp('\\b(' + terms[kw] + ')\\b', 'gi'),
            function (match) 
            {
              var link = document.createElement('a');
              link.href = 'http://www.okisurf.com/#q=' + terms[kw];
              link.id = '1';
              link.target = '_blank';
              link.innerHTML = match;
              return link;
            }
        );
    }
}());​

誰かがループを止めて、最初のキーワード一致のみを置き換えるのを手伝ってくれませんか? (私はそれらのノードとvar found、関数のためにスレッドがループで動作している間、グローバルのように送信できないことに夢中になっていfindKW()ます...)そして、ライブラリなし(jQueryまたはその他なし)

4

2 に答える 2

2

単語を置き換えたときに戻りtrue、再帰を停止するかどうかをテストできます。

if (child.nodeType == 1) { // ELEMENT_NODE
    tag = child.nodeName.toLowerCase();
    if (!(tag in skipTags)) {
        // If `findKW` returns `true`, a replacement as taken place further down
        // the hierarchy and we can stop iterating over the other nodes.
        if (findKW(child, term, replFn)) {
            return true;
        }
    }
} else if (child.nodeType == 3) { // TEXT_NODE
    if (replaceKW(child, term, replFn)) {
        return true;
    }
}

また、この関数内の参照を削除しfoundます。必要ありません。

デモ (関数も更新しました。replaceKWとにかく最初のものだけを使用している場合は、すべての一致を収集する必要はありません) .

于 2012-11-20T18:46:29.543 に答える
0

ループ ブロックから抜け出すには、break ステートメントを使用します。

例 :

for(;;) {
   if(condition) 
     break;
}

あなたの場合、これを次の位置に追加する必要があります

else if (child.nodeType == 3) 
{ // TEXT_NODE
     found=replaceKW(child, term, replFn);
     if(found)
       break; // or alternately use return;
}
于 2012-11-20T18:45:16.280 に答える