Aunque no es tan bonita como querySelectorAll
(que tiene una letanía de problemas), aquí hay una función muy flexible que recurre al DOM y debería funcionar en la mayoría de los navegadores (antiguos y nuevos). Siempre que el navegador admita su condición (es decir, atributos de datos), debería poder recuperar el elemento.
Para los curiosos: no se molesten en probar esto vs. QSA en jsPerf. Los navegadores como Opera 11 almacenarán en caché la consulta y sesgarán los resultados.
Código:
function recurseDOM(start, whitelist)
{
/*
* @start: Node - Specifies point of entry for recursion
* @whitelist: Object - Specifies permitted nodeTypes to collect
*/
var i = 0,
startIsNode = !!start && !!start.nodeType,
startHasChildNodes = !!start.childNodes && !!start.childNodes.length,
nodes, node, nodeHasChildNodes;
if(startIsNode && startHasChildNodes)
{
nodes = start.childNodes;
for(i;i<nodes.length;i++)
{
node = nodes[i];
nodeHasChildNodes = !!node.childNodes && !!node.childNodes.length;
if(!whitelist || whitelist[node.nodeType])
{
//condition here
if(!!node.dataset && !!node.dataset.foo)
{
//handle results here
}
if(nodeHasChildNodes)
{
recurseDOM(node, whitelist);
}
}
node = null;
nodeHasChildNodes = null;
}
}
}
Luego puede iniciarlo con lo siguiente:
recurseDOM(document.body, {"1": 1});
por velocidad, o simplemente recurseDOM(document.body);
Ejemplo con su especificación: http://jsbin.com/unajot/1/edit
Ejemplo con especificaciones diferentes: http://jsbin.com/unajot/2/edit
document.querySelectorAll
no funciona en IE7. Tendría que crear un script de respaldo que recorriera el árbol DOM y verificara el atributo en cada etiqueta (en realidad, no tengo idea de qué tan rápidoquerySelectorAll
es, e iría a la verificación manual de las etiquetas).