2

我正在尝试执行递归函数来按类查找 HTMLelement,但由于某种原因,它在到达没有子元素的子元素后停止。这是代码:


var alpha = Obj.elementByClass(document.body, "message");

Obj.elementByClass = function(element, cl) {
   var elementChildren = element.children,
       elementChildrenLength = elementChildren.length;

   for(var num=0; num<elementChildrenLength; num++) {
      if(elementChildren[num].className && elementChildren[num].className.indexOf("cl") > -1) {
         return elementChildren[num];
      }
      else if(elementChildren[num].children.length !=0) {
         return Obj.elementByClass(elementChildren[num], cl);
      }
   }
};

请不要建议 jquery 或其他库,我想了解为什么当它到达没有孩子的元素时它会停止。

谢谢!

4

5 回答 5

1
Obj.elementByClass = function(element, cl) {
   for(var i=0, len = element.children.length; i<len; i++) {
    if (element.children[i].className && new RegExp('\\b'+cl+'\\b').test(element.children[i].className))
       return element.children[i];
    else if(element.children[i].children.length)
       return Obj.elementByClass(element.children[i], cl);
   }
};

几点:

  • 您在定义之前调用了该函数(并且,由于这不是一个提升的函数,所以会出错)
  • 该类的测试现在更严格了,因为它现在不允许在共享相同单词的其他类名中找到类名(现在使用 REGEXP 完成检查,使用单词边界)
  • indexOf()正在明确寻找字符串“cl”,我认为您的意思是参数cl
  • 为了便于阅读,我把它剪掉了一点
  • 由于代码当前,您只返回第一个匹配节点,而不是全部
于 2012-07-06T10:44:33.500 回答
1

据我所知,您正在搜索带有 className 'message' 的 body 元素的第一个子元素。我可以建议这个替代方案吗?

document.querySelector('body .message')

函数返回undefined是因为第一个条件 ANDelse if(elementChildren[num].children.length !=0)两者都不为真。所以,什么都不做,退出,什么都没有返回。

于 2012-07-06T10:52:10.857 回答
1

因为for当元素没有子元素时,循环永远不会执行,因为两者都存在num并且条件永远不会为真。elementChildrenLength0num<elementChildrenLength

于 2012-07-06T10:36:00.757 回答
1

非元素节点(例如文本节点)没有 childNodes 属性,因此尝试读取.children.length它们会引发错误,从而中止执行。

您必须验证该节点是一个元素:

for(var num=0; num<elementChildrenLength; num++) {
    if (elementChildren[num].nodeType !== 1) {
        continue;
    }
    ...

或者在访问之前检查节点是否有 childNodes 属性:

else if(elementChildren[num].children && elementChildren[num].children.length !=0) {
于 2012-07-06T10:36:48.027 回答
1

如果elementChildrenLength等于 0,那么整个 for 循环块将不会执行。

避免这种情况的最佳方法是用以下内容包装 for 循环块:

if(elementChildrenLength==0){
    return 0;
}else{
   for(var num=0; num<elementChildrenLength; num++) {
       //for loop block here
   }
}
于 2012-07-06T10:37:46.073 回答