2011-03-09 14 views
9

Estoy trabajando en una biblioteca Javascript que trae jQuery para una cosa: un selector "termina con". Se ve así:ID termina con en Javascript puro

$('[id$=foo]') 

que encontrará los elementos en los que el id termina con "foo".

Estoy buscando hacer esto sin jQuery (directamente JavaScript). ¿Cómo puedes hacer esto? También me gustaría que sea tan eficiente como sea razonablemente posible.

+1

¿Puede proporcionar más información? ¿A qué tipo de elementos dom estás apuntando? ¿Es solo DIVs y SPANs o algo? – DhruvPathak

+0

Por lo que puedo decir, todas son etiquetas de entrada, pero la consulta anterior no especifica eso. Estoy volviendo a trabajar en una biblioteca existente, por lo que no puedo estar completamente seguro. –

Respuesta

10

Uso querySelectorAll, not available in all browsers (like IE 5/6/7/8) though. Básicamente funciona como jQuery:

http://jsfiddle.net/BBaFa/2/

console.log(document.querySelectorAll("[id$=foo]")); 
+1

Necesito este código para trabajar en todas partes, pero +1 para la introducción a JS Fiddle. ¡Muy genial! –

+0

¿En qué navegadores funciona? –

+0

Use '[attribute^= value]' para los elementos cuyo * valor * attribute * comience con un * value * especificado. – stil

1

Tendrá que iterar sobre todos los elementos en la página y luego usar las funciones de cadena para probarlo. Las únicas optimizaciones que puedo pensar es cambiar el punto de partida, es decir, no document.body, pero algún otro elemento del que sabe que su elemento será hijo o puede usar document.getElementsByTagName() para obtener una lista de elementos si conoce el nombre de la etiqueta de los elementos .

Sin embargo, su tarea sería mucho más fácil si pudiera utilizar JavaScript de terceros, p. Ej. Sizzle (4k minificado, el mismo motor selector que utiliza jQuery).

0

Si conoce el tipo de elementos DOM a los que se dirige, , obtenga una lista de referencias utilizando el getElementsByTagName y repítelos.

Puede utilizar esta optimización para sujetar las iteraciones:

  • ignoran los elementos no tener identificación.

  • objetivo el padre más cercano conocido de elementos que desea buscar, digamos que su elemento es dentro de un div con id = 'myContainer', entonces se puede obtener un subconjunto restringido el uso de document.getElementById('myContainer').getElementsByTagName('*'), y luego iterar sobre ellos.

1

Por lo tanto, el uso de todo lo dicho, he creado este código. Suponiendo que mis elementos son todos input s, entonces el siguiente código es probablemente lo mejor que voy a obtener?

String.prototype.endsWith = function(suffix) { 
    return this.indexOf(suffix, this.length - suffix.length) !== -1; 
}; 

function getInputsThatEndWith(text) { 

    var result = new Array(); 
    var inputs = document.getElementsByTagName("input"); 

    for(var i=0; i < inputs.length; i++) { 
     if(inputs[i].id.endsWith(text)) 
      result.push(inputs[i]); 
    } 

    return result; 
} 

lo puse en jsFiddle: http://jsfiddle.net/MF29n/1/

1

@ThiefMaster se refirió a cómo se puede hacer el registro de entrada, pero aquí está el código real:

function idEndsWith(str) 
{ 
    if (document.querySelectorAll) 
    { 
    return document.querySelectorAll('[id$="'+str+'"]'); 
    } 
    else 
    { 
    var all, 
     elements = [], 
     i, 
     len, 
     regex; 

    all = document.getElementsByTagName('*'); 
    len = all.length; 
    regex = new RegExp(str+'$'); 
    for (i = 0; i < len; i++) 
    { 
     if (regex.test(all[i].id)) 
     { 
     elements.push(all[i]); 
     } 
    } 
    return elements; 
    } 
} 

Esto se puede mejorar en una serie de formas. En la actualidad itera por el Reino toda, pero sería más eficiente si tenía un contexto:

function idEndsWith(str, context) 
{ 
    if (!context) 
    { 
    context = document; 
    } 
    ...CODE... //replace all occurrences of "document" with "context" 
} 

No hay ninguna validación/escapar de la variable str en esta función, el supuesto es que sólo va recibir una cadena de caracteres.

1

cambios sugeridos a your answer:

RegExp.quote = function(str) { 
    return str.replace(/([.?*+^$[\]\\(){}-])/g, "\\$1"); 
}; // from https://stackoverflow.com/questions/494035/#494122 

String.prototype.endsWith = function(suffix) { 
    return !!this.match(new RegExp(RegExp.quote(suffix) + '$')); 
}; 

function getInputsThatEndWith(text) { 

    var results = [], 
     inputs = document.getElementsByTagName("input"), 
     numInputs = inputs.length, 
     input; 

    for(var i=0; i < numInputs; i++) { 
     var input = inputs[i]; 
     if(input.id.endsWith(text)) results.push(input); 
    } 

    return results; 
} 

http://jsfiddle.net/mattball/yJjDV/

La implementación String.endsWith utilizando una expresión regular en lugar de indexOf() es sobre todo una cuestión de preferencia, pero pensé que valía la pena incluso para la variedad. Si no le preocupa la posibilidad de que se escapen caracteres especiales en el sufijo, puede eliminar el bit RegExp.quote() y simplemente usar
new RegExp(suffix + '$').

Cuestiones relacionadas