0

我已经修改了一个 dom 搜索/替换脚本,以通过链接替换文档中匹配的多个关键字。

它在没有任何<div>or的情况下工作得很好<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此函数中的任何引用,它不是必需的。

DEMO (我还更新了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 回答