如何以类型安全的方式从DOM节点(而不是元素)获取属性?

时间:2017-02-07 22:56:26

标签: javascript dom flowtype

我正在编写一个擦除DOM的函数,而我正在使用Flow来保证类型安全。

假设我有一些DOM Node选择器.foo > span的任意集合,每个集合都有一个数据属性data-foo

如果我想要每个data-foo,我通常会这样做:

// grab NodeList & convert to array
const fooNodeArray = Array.from(document.querySelectorAll('.foo > span'))

fooNodeArray.map(node => {
  return node.getAttribute('data-foo')
})

但根据Flow,这不是类型安全的,因为the Node type并不总是有方法getAttribute()

getAttribute()attributes时,Node(或相关的Node成员)仅存在于Element Node上(即{ {1}})。

如果这些Node.nodeType === 1Elements或具体id,我可以使用className,但不幸的是,它们只能通过getElementById()/-className()进行选择。

所以我尝试过这样的事情:

.foo > span

......但Flow继续拒绝它。

我非常确定这个fooNodeArray.map(node => { return node.nodeType === 1 ? node.getAttribute('data-foo') : null }) 后卫可以防范nodeType,但我试图避免忽略Flow(或使用TypeErrors来抑制错误)。

是否有一种类型安全的方法可以使用//$FlowFixMeattribute获取DOM Node

1 个答案:

答案 0 :(得分:1)

DOM级别4中的

Node不再具有属性(请参阅https://developer.mozilla.org/en/docs/Web/API/Nodehttps://developer.mozilla.org/en-US/docs/Web/API/Attr);相反,属性仅在Element上生存,因此您可能需要向Flow指出node => { ... }箭头函数中node参数的类型为Element,而不是泛型类型{{1 }}

请注意,这在技术上已经是这种情况,因为Node 返回通用NodeList,但特别是包含document.querySelectorAll个对象的NodeList(请参阅https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelectorAll) 。所以,这是另一种选择:如果你能告诉Flow你的ElementfooNodeArray而不是Element[],那么它就不应再抱怨Node[]了。