为了账号安全,请及时绑定邮箱和手机立即绑定

从头开始编写 getElementByName

从头开始编写 getElementByName

森林海 2022-01-07 10:25:24
我正在尝试从头开始编写 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};问题是我每个子节点都有一个数组,而不是同一个数组结果中的所有内容。我该如何解决这个问题?
查看完整描述

3 回答

?
海绵宝宝撒

TA贡献1809条经验 获得超8个赞

所以你试图通过递归函数遍历 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

};


此实现应仅用于教育目的,因为它具有很大的存储复杂性。


查看完整回答
反对 回复 2022-01-07
?
肥皂起泡泡

TA贡献1829条经验 获得超6个赞

您可以像这样使用 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}`)

);


查看完整回答
反对 回复 2022-01-07
?
眼眸繁星

TA贡献1873条经验 获得超9个赞

这样的事情应该这样做:


const getElementsByClassName  = (name, el) => 

  [

    ... (el .classList .contains (name) ? [el] : []),

    ... ([... el .childNodes] .flatMap (c => getElementsByClassName (name, c)))

  ]

从逻辑上讲,这只是说将测试该节点(使用它的classList)的结果与flatMap对其子节点的ped 递归调用相结合。


现场示例:

const getElementsByClassName  = (name, el) => 

  [

    ... ([...(el .classList || [])] .includes (name) ? [el] : []),

    ... ([... el .childNodes] .flatMap (c => getElementsByClassName (name, c)))

  ]


console .log (

  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'>

  Baz

  <div class = 'baz qux'>

    Qux 

    <div class = 'foo baz qux'>Foo Baz Qux</div>

  </div>

  <div class = 'baz foo'>Baz Foo</div>

</div>

这在 DOM 遍历中可能过于简单,因为并非所有子节点都是元素,但这可能只是第二次检查。这应该表明这个想法。


查看完整回答
反对 回复 2022-01-07
  • 3 回答
  • 0 关注
  • 211 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号