查找没有库或getElementsByClassName的类的元素

时间:2014-11-13 22:08:35

标签: javascript html

这是我被问到的问题,我想知道该怎么做或者它是否是一个技巧问题。我一直只使用JavaScript,所以我不太确定。

假设您有一个包含大量内容的网页。 不使用任何库或getElementsByClassName ,遍历DOM并查找具有特定类名的所有元素。

示例HTML

<body>
    <div>
        <div class='myTarget'>
             Target exists here
        </div>
    </div>

    <div>
        <table>
            <tbody>
              <tr> <td class='myTarget'> Target exists here </td> </tr>
            </tbody>
        </table>
    </div>

    <div>
       <span class='myTarget notSameAsTarget'>Stuff<span>
    </div>

</body>

我的第一个想法是,这应该是一个递归函数,应该从根document.documentElement开始

JS:

var root = document.documentElement;
var targetClass = 'myTarget';
var elementsWithTargetClass = []; // store in array

function traverse(element, targetClassName){
    // get class of current element
    var currentClass = element.className;

    // add to array if class matches
    if(currentClass.trim() === targetClassName)
        elementsWithTargetClass.push(element);

    // recursive call
    if(element.children){
         traverse(element, targetClassName);
    }

}

有关我失踪的建议吗?

    // recursive call - updated
    if(element.children){
         for(var child in element.children)
             traverse(element.children[child], targetClassName);
    }

5 个答案:

答案 0 :(得分:8)

你对traverse()的递归调用传递了最初传入的相同元素,所以它只是一遍又一遍地做同样的事情,直到堆栈溢出(嘿!)。您需要为元素的每个子元素调用遍历,而不是将元素重新传入。

答案 1 :(得分:2)

使用document.querySelector。这不是getElementsByClassName(),也不是库。 ;)

document.querySelector('.myTarget')

答案 2 :(得分:2)

考虑具有多个类的元素,并以body开头:

&#13;
&#13;
  var targetClass = 'myTarget';
  var elementsWithTargetClass = []; // store in array
  var re = new RegExp("\\b" + targetClass + "\\b");
  
  traverse(document.body);
  
  for ( var j = 0; j < elementsWithTargetClass.length; ++j )
    elementsWithTargetClass[j].style.fontWeight = "bold";
  
  function traverse(element, targetClassName){
      // get class of current element
      var currentClass = element.className;
  
      if (currentClass.match(re))
      // add to array if class matches
    //  if(currentClass.trim() === targetClassName)
          elementsWithTargetClass.push(element);
  
      // recursive call
      if(element.children){
        for ( var i = 0; i < element.children.length; ++i )
           traverse(element.children[i]);
      }
  }
&#13;
<div>
  <ul>
    <li class="myTarget">this</li>
    <li class="myTarget andAnotherClass">also this</li>
    <li>not this</li>
  </ul>
</div>
&#13;
&#13;
&#13;

答案 3 :(得分:1)

您正在进行许多递归,这使得调用堆栈变得很高。尝试将递归函数转换为循环。这不应该给你任何问题。

答案 4 :(得分:1)

var root = document.documentElement;
var targetClass = 'myTarget';
var elementsWithTargetClass = []; // store in array
pre_order(root);

function pre_order(node) {
  if(node.className == targetClass) 
    elementsWithTargetClass.push(node);       
  for(var i=0; i < node.childNodes.length; i++)
    pre_order(node.childNodes[i]);
}
console.log(elementsWithTargetClass);

JSFiddle