Javascript: Localizar nodos del DOM

Javascript dispone de tres funciones para localizar nodos.

getElementById(id)
Recibe el id del elemento que se quiere encontrar, y lo retorna.
getElementsByName(name)
Recibe un nombre, y retorna una lista de nodos con ese nombre en su atributo name.
getElementsByTagName(tagName)
Recibe el nombre de nodo (p.ej: input, div, img...), y retorna una lista de nodos de ese tipo.

Éstas son las estándares, pero muchos frameworks poseen los suyos propios (algunos extremadamente ineficientes) además de muchos otros algoritmos que rondan por foros y blogs más visitados que éste.

Pero ¿qué ocurre si quiero filtrar sus resultados según el valor de algún otro de sus atributos? Sencillo: buscamos usando alguno de los estándares y filtramos.

Podéis bajar el mismo código (0.5KiB) o la versión minificada (0.3KiB) de las descargas del blog en Google Code.

function require(a,o){
/* Filter a list of DOM nodes by theirs attributes
* a: hash with attribute name as key, and attributes value (or cmp function) as value
* b: list of DOM nodes
*/
var tr=[];
for(var j in a){if(typeof(a[j])!="function"){
a[j]=(function(a){return function(v){return v==a;}}(a[j]));}}
for(var i=0,l=o.length,j,k;i<l;i++){
k=1;
for(var j in a){
k=(typeof(o[i][j])!="undefined")&&(a[j](o[i][j]));}
if(k){tr[tr.length]=o[i];}}
return tr;
}

Tengo la buena costumbre de comentar el código en inglés, pero por si acaso explico, recibe un objeto hash (o diccionario) con los atributos a buscar y sus valores (o funciones de comparación), y una lista de nodos del DOM.

Siempre habrá que pasarle una lista de nodos puesto que se trata simplemente de un filtro. Pero puesto que los atributos posibles dependen directamente del tipo de nodo, usarlo en conjunción con getElementsByTagName es bastante trivial.

Usarlo es muy sencillo y potente, como ejemplo vamos a buscar todos los botones de envío de formulario.

var submits=require(
{type:"submit"},
document.getElementsByTagName("input"));

O buscamos los cuadros de selección que estén activados.

var checkedboxes=require(
{checked:"checked"},
document.getElementsByTagName("checkbox"));

Y también permite especificar filtros personalizados.

var divs=require(
{className:function(v){
return v.search("test")>-1;}},
document.getElementsByTagName("div"));

Como veis, es un método muy sencillo a la par que útil.

0 comentarios:

Publicar un comentario