假设我有以下标记......
<div data-namespace-title="foo"></div>
<div data-namespace-description="bar"></div>
<div data-namespace-button="foo"></div>
无论如何,我可以用querySelectorAll
选择它们吗?
我已经尝试了document.querySelectorAll([data-namespace-*])
,但这当然不起作用
答案 0 :(得分:1)
没有简单的方法,只是因为浏览器没有在属性名称/键上实现通配符选择器(仅限于其值)。你可以做的是简单地遍历你的元素集(在这种情况下,它们的公分母是div
),然后过滤掉它们。
您可以通过调用<Node>.attributes
来访问每个DOM节点的属性列表,然后将其转换为数组,并检查每个属性name
中的一个或多个是否与正则表达式模式匹配{{ 1}}:
/^data-namespace-.*/gi
var els = document.querySelectorAll("div");
var filteredEls = Array.prototype.slice.call(els).filter(function(el) {
var attributes = Array.prototype.slice.call(el.attributes);
// Determine if attributes matches 'data-namespace-*'
// We can break the loop once we encounter the first attribute that matches
for (var i = 0; i < attributes.length; i++) {
var attribute = attributes[i];
// Return the element if it contains a match, and break the loop
if (attribute.name.match(/^data-namespace-.*/gi))
return el;
}
});
console.log(filteredEls);
更新:如果您熟悉ES6,它会变得更加清晰,因为:
Array.from
代替繁琐的<div data-namespace-title="foo">title</div>
<div data-namespace-description="bar">description</div>
<div data-namespace-button="foobar">button</div>
<div data-dummy>dummy</div>
。专业提示:您也可以使用点差运算符,即Array.prototype.slice.call(...)
。Array.some
代替手动创建带有返回逻辑的const els = [...document.querySelectorAll("div")]
循环
for
const els = Array.from(document.querySelectorAll("div"));
const filteredEls = els.filter(el => {
const attributes = Array.from(el.attributes);
return attributes.some(attribute => attribute.name.match(/^data-namespace-.*/gi));
});
console.log(filteredEls);
答案 1 :(得分:1)
不确定您是否愿意更改属性的格式,但如果您想使用querySelectorAll
Array.from(document.querySelectorAll('[data-namespace]')).forEach(el => {
console.log(el.getAttribute('data-value'))
})
<div data-namespace="title" data-value="foo"></div>
<div data-namespace="description" data-value="bar"></div>
<div data-ns="button" data-value="foo"></div>
<div data-namespace="button" data-value="foo"></div>
您的另一个选择是使用xpath。
注意:使用iterateNext()
时,如果您在调用文档之前修改文档,它将会中断。
var divs = document.evaluate('//@*[starts-with(name(.), "data-namespace")]', document, null, XPathResult.ANY_TYPE, null);
var div = divs.iterateNext()
while (div) {
alert(div.ownerElement.textContent)
div = divs.iterateNext()
}
<div data-namespace-title="foo">Foo</div>
<div data-namespace-description="bar">Bar</div>
<div data-ns-button="foo">NS Foo</div>
<div data-namespace-button="foo">Foo</div>
答案 2 :(得分:0)
这样的事情没有内置的选择器,但你仍然可以通过选择所有元素然后过滤那些具有以data-namespace
开头的属性的方式来轻松完成它: / p>
console.log(
[...document.querySelectorAll('*')]
.filter(({ attributes }) =>
[...attributes].some(({ name }) => name.startsWith('data-namespace'))
)
);
&#13;
<div data-baz="baz"></div>
<div data-namespace-title="foo"></div>
<div data-namespace-description="bar"></div>
<div data-namespace-button="foo"></div>
&#13;