【发布时间】:2016-05-03 01:25:05
【问题描述】:
我在电话采访中被要求写一个document.querySelector/document.querySelectorAll polyfill,使用以下内容
document.getElementByIddocument.getElementsByClassNamedocument.getElementsByTagName
polyfill 应该能够采用 css 选择器的任意组合,例如 .foo p.bar.baz span.qax。
我想不出合适的解决方案。
我的方法...
...是解析selector并开始向右。
关于.foo p.bar.baz span.qax
- 我想将选择器解析为
['.foo', ['p', '.bar', '.baz'], ['span', '.qax'] - 取最右边的元素,
- 如果是数组,对于数组最右边的元素,使用可用方法获取节点。
- 否则对于数组最右边的元素,使用可用方法获取节点
- 并根据左侧的剩余选择器过滤可用节点
我在哪里失败了?
- 我找不到解析选择器的正则表达式
我想我应该从解析选择器的左侧而不是右侧开始。
我搜索了document.queryselector polyfill,但在大多数可用的解决方案中都无法理解{x:expression(document.__qsaels.push(this))}。
任何指针都会有所帮助。谢谢!
更新 w.r.t. cmets
感谢大家的建议/cmets。
@Sitian Liu,我的主要查询是“如何严格执行 querySelectorAll 与 document.getElementById、document.getElementsByClassName、document.getElementsByTagName”我想我可以加入 {x:expression(document.__qsaels.push(this))} 感谢 @RobG 提供指向 What does {x:expression(...)} do? 的指针.
@SravanS,对不起,我不知道你对heavy 的定义是什么,但是给我的选择器有classes、tags 和child selector。
Polyfill 有意省略了属性选择器
@guest271314 我不记得是否存在属性选择器。我猜是故意省略的
@SravanS 我很欣赏你的 cmets,但我不敢说你假设太多了。面试官确实想针对 HTML 标记干运行代码。
@SravanS @jfriend00 我知道sizzle,我认为我可以在 StackOverflow 中轻松理解答案,而不是阅读 2242 行代码。 :)
@RobG 回应了我的担忧。
在完成所有 cmets 之后,我想知道这个问题是否应该成为 30 分钟电话面试过程的一部分,当您必须在 Google Doc 中对其进行实时编码时也是如此。
【问题讨论】:
-
嘿,你是在问
document.__qsaels.push(this)是关于什么的,或者如何通过严格的document.getElementById实现querySelectorAlldocument.getElementsByClassNamedocument.getElementsByTagName。这是两个截然不同的问题 -
我认为,您不应该尝试一次解析所有数据,而且我认为,他们不希望您解析繁重的 CSS 选择器,例如
p.class1 #op ~ .class2 -
“我在一次电话采访中被要求写一个 document.querySelector/document.querySelectorAll polyfill,故意使用以下 document.getElementById document.getElementsByClassName document.getElementsByTagName” Polyfill省略属性选择器?
-
一般来说,我的方法是先用空格分割整个选择器,然后得到一个数组,然后取出这个数组中的每个元素,并用
#和.分割它们,这给出了你想要的数据结构。 -
@SravanS - 当不支持
querySelectorAll()时,jQuery 使用Sizzle selector engine 回填(现在只有旧浏览器缺少该功能)。 jQuery 还对选择器语法进行了自己的补充(超出了querySelectorAll()支持它必须检查的内容。
标签: javascript dom polyfills selectors-api