是否可以像 getElementsByTagName 一样让 querySelectorAll 生效?
Is it possible to make querySelectorAll live like getElementsByTagName?
getElementsByTagName()
有两大特点:速度快,而且是实时的。但是如果我想得到 p strong
怎么办?当然,我可以再次使用 getElementsByTagName()
优化选择,但我不会失去新 p
标签的实时效果吗?
有没有办法将 querySelectorAll
变成实时选择器?
或者...有没有一种方法可以使用 getElementsByTagName()
和 getElementsByClassName()
来创建一个与 querySelectorAll
工作方式相似的函数(至少对于后代)直播?
我认为这是不可能的,因为 DOM 的后续更改不会反映在 querySelectorAll() 方法返回的 NodeList 对象中。
考虑使用突变观察器。用 subtree: true
观察 childList
。当通知到达时,您可以使用 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;
}
getElementsByTagName()
有两大特点:速度快,而且是实时的。但是如果我想得到 p strong
怎么办?当然,我可以再次使用 getElementsByTagName()
优化选择,但我不会失去新 p
标签的实时效果吗?
有没有办法将 querySelectorAll
变成实时选择器?
或者...有没有一种方法可以使用 getElementsByTagName()
和 getElementsByClassName()
来创建一个与 querySelectorAll
工作方式相似的函数(至少对于后代)直播?
我认为这是不可能的,因为 DOM 的后续更改不会反映在 querySelectorAll() 方法返回的 NodeList 对象中。
考虑使用突变观察器。用 subtree: true
观察 childList
。当通知到达时,您可以使用 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;
}