是否可以让 querySelectorAll 像 getElementsByTagName 一样生活?
Posted
技术标签:
【中文标题】是否可以让 querySelectorAll 像 getElementsByTagName 一样生活?【英文标题】:Is it possible to make querySelectorAll live like getElementsByTagName? 【发布时间】:2015-08-15 05:14:00 【问题描述】:getElementsByTagName()
有 2 个很棒的功能:速度快,而且是实时的。但是如果我想得到p strong
怎么办?当然,我可以再次使用getElementsByTagName()
优化选择,但我不会失去新的p
标签的实时效果吗?
有没有办法将querySelectorAll
变成实时选择器?
或者...有没有办法使用getElementsByTagName()
和getElementsByClassName()
来创建一个与querySelectorAll
以类似方式(至少对于后代)但正在运行的函数?
【问题讨论】:
这样的特性,如果在本地实现,可能会被排除在动态配置文件之外,防止使用像:has()
这样的级别 4 选择器和复杂的选择器,因为实时选择器匹配基本上是 CSS 中发生的事情因此对性能很敏感。不过,我很想知道。
【参考方案1】:
考虑使用变异观察者。关注childList
和subtree: true
。当通知到达时,您可以使用matches
检查每个添加的节点,以查看它是否与某些选择器匹配。
function querySelectorAllLive(element, selector)
// Initialize results with current nodes.
var result = Array.prototype.slice.call(element.querySelectorAll(selector));
// Create observer instance.
var observer = new MutationObserver(function(mutations)
mutations.forEach(function(mutation)
[].forEach.call(mutation.addedNodes, function(node)
if (node.nodeType === Node.ELEMENT_NODE && node.matches(selector))
result.push(node);
);
);
);
// Set up observer.
observer.observe(element, childList: true, subtree: true );
return result;
【讨论】:
这看起来不错,但我在 target.matches 上遇到错误。你试过这个吗?我刚刚创建了一支笔:codepen.io/vandervals/pen/Nqpxww?editors=101 对不起,应该是observer.observe(element
。
它是subtree
而不是subTree
。现在它起作用了。对不起。
现在没有错误,但是当我按下给我的时候!我没有得到新元素...你能再检查一下笔吗?
天哪。看起来我必须更好地测试我的代码。查看修复。【参考方案2】:
我认为这是不可能的,因为 DOM 的后续更改不会反映在 querySelectorAll() 方法返回的 NodeList 对象中。
Selectors-api W3C
【讨论】:
以上是关于是否可以让 querySelectorAll 像 getElementsByTagName 一样生活?的主要内容,如果未能解决你的问题,请参考以下文章
querySelectorAll 是不是支持 id 中的句点(.)字符?
如何将 querySelectorAll() 函数添加到 IE <= 7 的 Element?
是否可以让 gradle 解析像 '5.0.+' 这样的 ivy 依赖项以获得像 '5.0.0.1.12.24' 这样的版本?