javascript - querySelector,获取属性以给定字符串开头的元素

标签 javascript html dom selectors-api

我正在寻找一种方法来查找包含以给定字符串开头的属性的所有元素。例如:

document.querySelectorAll('[ng-*]') 将返回带有 Angular 指令的所有元素(ng-clickng-showng-hide...)。

但是通配符似乎不起作用。

有什么想法吗?我可以实现我自己的,但它不会那么有效。

最佳答案

没有 CSS 选择器可以让您在属性的名称上使用通配符,而只能在值上使用通配符,这显然不是您想要的。

不幸的是,您必须手动完成这项工作。

如果您知道要处理的列表很小,您可以使用简单版本的“先查询后过滤”来完成;如果您认为它可能更大,DOM walker 解决方案(见下文)可能会更好。

简单的查询然后过滤(ES2015 语法):

// Best if you can use *some* selector in the querySelectorAll rather than just *
// to keep the list to a minimum
let elements =
  [...document.querySelectorAll("*")].filter(
    element => [...element.attributes].some(
      attr => attr.nodeName.startsWith("ng-")
    )
  );
console.log(elements);
<div></div>
<div ng-bar></div>
<div></div>
<div ng-foo></div>
<div></div>

ES5 版本:

var elements = Array.prototype.filter.call(
  document.querySelectorAll("*"), // Best if you can use *something* here
                                  // to keep the list to a minimum
  function(element) {
    return Array.prototype.some.call(
      element.attributes,
      function(attr) {
        return attr.nodeName.startsWith("ng-");
      }
    );
  }
);
console.log(elements);
<div></div>
<div ng-bar></div>
<div></div>
<div ng-foo></div>
<div></div>

<小时/>

Walker解决方案(ES2015+):

function domFind(element, predicate, results = []) {
  if (!element.children) {
    throw new Error("Starting node must be an element or document");
  }
  if (predicate(element)) {
    results.push(element);
  }
  if (element.children && element.children.length) {
    [...element.children].forEach(child => {
      domFind(child, predicate, results);
    });
  }
  return results;
}
let elements = domFind(document, element => {
  return element.attributes && [...element.attributes].some(attr => attr.nodeName.startsWith("ng-"));
});
console.log(elements);
<div></div>
<div ng-bar></div>
<div></div>
<div>
  <div>
    <div ng-foo></div>
  </div>
  <div ng-baz></div>
</div>
<div></div>

ES5:

function domFind(element, predicate, results) {
  if (!results) {
    results = [];
  }
  if (!element.children) {
    throw new Error("Starting node must be an element or document");
  }
  if (predicate(element)) {
    results.push(element);
  }
  if (element.children && element.children.length) {
    Array.prototype.forEach.call(element.children, function(child) {
      domFind(child, predicate, results);
    });
  }
  return results;
}
var elements = domFind(document, function(element) {
  return element.attributes && Array.prototype.some.call(element.attributes, function(attr) {
    return attr.nodeName.startsWith("ng-");
  });
});
console.log(elements);
<div></div>
<div ng-bar></div>
<div></div>
<div>
  <div>
    <div ng-foo></div>
  </div>
  <div ng-baz></div>
</div>
<div></div>

<小时/>

对于上述所有内容,请注意 String#startsWith 在 ES2015 之前可能需要垫片。

关于javascript - querySelector,获取属性以给定字符串开头的元素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38672813/

相关文章:

javascript - 表单内的单击事件监听器

html - 没有JQuery的DIV自动设置高度

javascript - 创建类似于fb :tag

html - 带有 _Blank 目标的 Mailchimp 按钮未在新窗口中打开 :(

javascript - 如何以 mat 形式将值变为小写

javascript - 重新计算/回流绝对定位元素网格的有效方法

javascript - Angularjs Dom 在加载模板时泄漏

javascript - JQuery 从页面 anchor 抓取内容并替换悬停状态标题

JavaScript 遍历表问题

javascript - Webpack - 捆绑多个/不同版本的 .css 文件