Get elements by attribute when querySelectorAll is not available without using libraries?

<p data-foo="bar">

How can you do the equivalent to

document.querySelectorAll('[data-foo]')

where querySelectorAll is not available?

I need a native solution that works at least in IE7. I don’t care about IE6.

283449 次浏览

您可以编写一个函数来运行 getElementsByTagName (’*’) ,并且只返回那些带有“ data-foo”属性的元素:

function getAllElementsWithAttribute(attribute)
{
var matchingElements = [];
var allElements = document.getElementsByTagName('*');
for (var i = 0, n = allElements.length; i < n; i++)
{
if (allElements[i].getAttribute(attribute) !== null)
{
// Element exists with attribute. Add to array.
matchingElements.push(allElements[i]);
}
}
return matchingElements;
}

然后,

getAllElementsWithAttribute('data-foo');

我玩了一会儿,最后得出了这个粗糙的解决方案:

function getElementsByAttribute(attribute, context) {
var nodeList = (context || document).getElementsByTagName('*');
var nodeArray = [];
var iterator = 0;
var node = null;


while (node = nodeList[iterator++]) {
if (node.hasAttribute(attribute)) nodeArray.push(node);
}


return nodeArray;
}

用法非常简单,甚至在 IE8中也可以使用:

getElementsByAttribute('data-foo');
// or with parentNode
getElementsByAttribute('data-foo', document);

Http://fiddle.jshell.net/9xaxf6jr/

但是我 推荐使用 querySelector/All(并且支持旧的浏览器使用 填料) :

document.querySelectorAll('[data-foo]');

使用

//find first element with "someAttr" attribute
document.querySelector('[someAttr]')

或者

//find all elements with "someAttr" attribute
document.querySelectorAll('[someAttr]')

现在所有相关的浏览器(甚至是 IE8)都支持: http://caniuse.com/#search=queryselector

试试这个-我稍微改变了上面的答案:

var getAttributes = function(attribute) {
var allElements = document.getElementsByTagName('*'),
allElementsLen = allElements.length,
curElement,
i,
results = [];


for(i = 0; i < allElementsLen; i += 1) {
curElement = allElements[i];


if(curElement.getAttribute(attribute)) {
results.push(curElement);
}
}


return results;
};

然后,

getAttributes('data-foo');

这也行得通:

document.querySelector([attribute="value"]);

所以:

document.querySelector([data-foo="bar"]);

不要在浏览器中使用

在浏览器中,使用 document.querySelect('[attribute-name]')

但是,如果您正在进行单元测试,并且您的模拟名称有一个古怪的 querySelector 实现,那么这就可以解决问题了。

这就是@kevinfahy 的答案,它只是简化了 ES6胖箭头函数,并以牺牲可读性为代价将 HtmlCollection 转换为数组。

所以只能用 ES6传送器。而且,我不确定它在很多元素下的性能如何。

function getElementsWithAttribute(attribute) {
return [].slice.call(document.getElementsByTagName('*'))
.filter(elem => elem.getAttribute(attribute) !== null);
}

这里有一个变量,它将获得一个具有特定值的属性

function getElementsWithAttributeValue(attribute, value) {
return [].slice.call(document.getElementsByTagName('*'))
.filter(elem => elem.getAttribute(attribute) === value);
}

试试这个,有用的

QuerySelector (’[ tribute = “ value”]’)

例如:

document.querySelector('[role="button"]')

对@kevinfahy 的 回答进行一些修改,以允许在需要时按值获取属性:

function getElementsByAttributeValue(attribute, value){
var matchingElements = [];
var allElements = document.getElementsByTagName('*');
for (var i = 0, n = allElements.length; i < n; i++) {
if (allElements[i].getAttribute(attribute) !== null) {
if (!value || allElements[i].getAttribute(attribute) == value)
matchingElements.push(allElements[i]);
}
}
return matchingElements;
}