从头开始编写 getElementByName

我正在尝试从头开始编写 getElementByClassName,但我不确定何时返回递归。这就是我想出的:


  const getElementsByClassName = (nameOfClass, parent) => {


  const result = []

  for(let el of parent) {

       // console.log(el.children)

     if(el.firstElementChild != null) {

       // do it again on node deeper

        getElementsByClassName(nameOfClass, el.children)

     }


     if(el.className === nameOfClass) {

        result.push(el)

     }

   }

   // when do I want to return result?

   console.log(result)

   return result


};

问题是我每个子节点都有一个数组,而不是同一个数组结果中的所有内容。我该如何解决这个问题?


森林海
浏览 246回答 3
3回答

海绵宝宝撒

所以你试图通过递归函数遍历 DOM 树!?当然,每个孩子都有自己的一组孩子。不然就不是树了。当您想要返回所有匹配元素的数组时,您必须将结果与递归调用连接起来。这可以工作:const getElementsByClassName = (nameOfClass, parent) => {  const result = []  if (parent.className === nameOfClass) {    result.push(parent);  }  for(let el of parent.children) {    result = result.concat(getElementByClassName(nameOfClass, el));   }   return result};此实现应仅用于教育目的,因为它具有很大的存储复杂性。

肥皂起泡泡

您可以像这样使用 querySelectorAll :const getElementsByClassName = (nameOfClass, ancestor) => ( ancestor.querySelectorAll(`.${nameOfClass}`));或者,如果您肯定想要父母的直系后代。es6方式:const getElementsByClassName = (nameOfClass, parent) => ( [...parent.querySelectorAll(`.${nameOfClass}`)].filter(item => item.parentElement === parent)));javascript方式const getElementsByClassName = (nameOfClass, parent) => ( Array.prototype.slice.call(parent.querySelectorAll(`.${nameOfClass}`)).filter(item => item.parentElement === parent)));很遗憾,我们不能将直接后代与 querySelectorAll 一起使用。否则这将是完美的:const getElementsByClassName = (nameOfClass, parent) => ( parent.querySelectorAll(`> .${nameOfClass}`));

眼眸繁星

这样的事情应该这样做:const getElementsByClassName&nbsp; = (name, el) =>&nbsp;&nbsp; [&nbsp; &nbsp; ... (el .classList .contains (name) ? [el] : []),&nbsp; &nbsp; ... ([... el .childNodes] .flatMap (c => getElementsByClassName (name, c)))&nbsp; ]从逻辑上讲,这只是说将测试该节点(使用它的classList)的结果与flatMap对其子节点的ped 递归调用相结合。现场示例:const getElementsByClassName&nbsp; = (name, el) =>&nbsp;&nbsp; [&nbsp; &nbsp; ... ([...(el .classList || [])] .includes (name) ? [el] : []),&nbsp; &nbsp; ... ([... el .childNodes] .flatMap (c => getElementsByClassName (name, c)))&nbsp; ]console .log (&nbsp; getElementsByClassName ('foo', document).map(el => el.textContent)).foo {background: yellow; font-weight: bold}<div class = 'foo'>Foo</div><div class = 'bar'>Bar</div><div class = 'baz'>&nbsp; Baz&nbsp; <div class = 'baz qux'>&nbsp; &nbsp; Qux&nbsp;&nbsp; &nbsp; <div class = 'foo baz qux'>Foo Baz Qux</div>&nbsp; </div>&nbsp; <div class = 'baz foo'>Baz Foo</div></div>这在 DOM 遍历中可能过于简单,因为并非所有子节点都是元素,但这可能只是第二次检查。这应该表明这个想法。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

JavaScript