追溯搜索以获得<a> element

时间:2018-08-08 18:35:30

标签: javascript

This is the heirarchy of an HTML

<tr..>
  <td..>
    <table..>
      <tbody..>
       <tr..>
        <td..>
          <a..>
        <td..>
       <tr..>
     <tbody..>
   <table..>
 <td..>
<tr..>

I am passing parent <tr> and "A" as parameters in below function and expecting <a..> element to be returned but its returnng me 2nd <td..> from top.

b = function  tryRecursiveSearch (node,tag) {
     var child, tag;
    for (var i = 0; i < node.children.length; i++) {

   var len =  node.children.length;
      child = node.children[i];

    if (child.tagName === "A"){
     console.log('a');
             }
    else {  
          tryRecursiveSearch (child,"A");
          }
    }
   return child;
}

What is missing in above code so that it returns <a>?

4 个答案:

答案 0 :(得分:0)

您可以尝试以下操作:

function tryRecursiveSearch(node, tag) {
    if (node.tagName === tag) {
        return true;
    } else {
        for (var i = 0; i < node.children.length; i++) {
            if (tryRecursiveSearch(node.children[i], tag)) {
                return true;
            }
        }
        return false;
    }
}

答案 1 :(得分:0)

在ES5中没有优化尾调用,tree walker不一定更快。您可以使用microtaskq进行此类操作,并传递回调以与节点一起执行。

输入

"<tr><td>
    <table>
      <tbody>
       <tr>
        <td>
          <a>
        </a></td>
       </tr>
     </tbody>
   </table>
 </td></tr>"

功能

function findTag(node,tag,callback,found){
    found = found || [];
    if(found.length){
        return
    };
    var children = Array.prototype.slice.call(node.children);
    children.some(function(d,i){
        if(d.tagName === tag.toUpperCase()){
            found.push(d);
            return true;
        }
    });
    if(found.length){
        callback(found);
    }   else {
        children.forEach(function(d,i){
            window.requestAnimationFrame(function(){
                findTag(d,tag,callback,found);
            })
        })
    }
}

用法

findTag(x,"a",function(node){console.log(node)})
//[a]

我将找到的变量保留为数组,您可以将函数修改为采用前n个元素左右。

答案 2 :(得分:0)

一个问题是return child;代码发生在for () {}循环之后,这意味着直到循环结束,它才触发。此时,child现在将包含循环处理的最后一个元素。

另一个,没有什么可以派遣子孙后代通过后代的,直到初始调用函数。

b = function tryRecursiveSearch(node, tag) {
  var child; // tag is available as an argument, setting this would reinitialize it as an empty variable
  for (var i = 0; i < node.children.length; i++) {

    var len = node.children.length;
    child = node.children[i];
    
    if (child.tagName === tag) {
      console.log('Found ' + tag);
      return child; // Return once the tag is found
    } else {
      child = tryRecursiveSearch(child, tag);
      if (child.tagName === tag) {
        return child; // Return if the tag is found as a descendant of this element
        // This is what allows a descendant to send the given tag up the recursion
       }
    }
  }
  // the variable child gets overwritten everytime the loop runs; using "return child;" here will result in returning the last child in the set of nodes; regardless of whether it is tag or not
}



console.log(b(document.getElementById('trParent'), 'A'))
<table>
  <tr id="trParent">
    <td>
      <table>
        <tr>
          <td>
            <a href="#">Link</a>
          </td>
        </tr>
      </table>
    </td>
  </tr>
</table>

答案 3 :(得分:0)

如上面@SLaks所指出的,这个简单的更改为我提供了a

if (child.tagName === "A"){
     return child;
             }
    else {  
          return tryRecursiveSearch (child,"A");
          }
    }

}