如何在找到第一个匹配时停止DOM搜索循环?

时间:2012-11-20 18:40:48

标签: javascript dom loops replace nodes

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

在没有任何<div><p>的情况下工作得很好,但是复杂的结构会替换每个节点的关键字......

这是example

正如您所看到的,相同的关键字在元素中没有多次链接,但是有一些其他元素关联的链接......

这是脚本

(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或其他)

2 个答案:

答案 0 :(得分: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功能,如果您只使用第一个匹配项,则无需收集所有匹配项

答案 1 :(得分: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;
}