是否可以让 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】:

考虑使用变异观察者。关注childListsubtree: 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?

jQuery的基本语法是?

是否可以让 gradle 解析像 '5.0.+' 这样的 ivy 依赖项以获得像 '5.0.0.1.12.24' 这样的版本?

如何在jquery中操作DOM

jquery中如何选择选取DOM元素?