sólo para hacer un poco de seguimiento, basé mi código en el la aplicación Robert Nyman publicado por Shog9, pero se apartó un poco de su versión exacta, por tres razones:
- permitió que seleccione un elemento fundamental y tipo de etiqueta para filtrar los resultados.No necesito esa funcionalidad y, al eliminarla, pude simplificar el código significativamente.
- Lo primero que su código hace es ver si la función en cuestión ya existe, y si lo hace, proporciona su propia implementación de todos modos. Eso solo parecía ... extraño. Entiendo que estaba agregando funcionalidad al original, pero de nuevo: no estoy usando esas funciones.
- Quería un poco más de azúcar sintáctico, para poder llamarlo como llamaría al
document.getElementById()
o document.getElementsByTagName()
.
Tenga en cuenta que todavía confié principalmente en su código. Sus habilidades de javascript obviamente van más allá del mío. Intenté factorizar algunas variables redundantes, pero eso es todo.
Con esto en mente, aquí es lo que terminó con (parece a trabajar en IE6, IE7, Firefox 3 y Chrome ver nota nueva al final):
if (!document.getElementsByClassName)
document.getElementsByClassName = function (className)
{
var classes = className.split(" ");
var classesToCheck = "";
var returnElements = [];
var match, node, elements;
if (document.evaluate)
{
var xhtmlNamespace = "http://www.w3.org/1999/xhtml";
var namespaceResolver = (document.documentElement.namespaceURI === xhtmlNamespace)? xhtmlNamespace:null;
for(var j=0, jl=classes.length; j<jl;j+=1)
classesToCheck += "[contains(concat(' ', @class, ' '), ' " + classes[j] + " ')]";
try
{
elements = document.evaluate(".//*" + classesToCheck, document, namespaceResolver, 0, null);
}
catch(e)
{
elements = document.evaluate(".//*" + classesToCheck, document, null, 0, null);
}
while ((match = elements.iterateNext()))
returnElements.push(match);
}
else
{
classesToCheck = [];
elements = (document.all) ? document.all : document.getElementsByTagName("*");
for (var k=0, kl=classes.length; k<kl; k+=1)
classesToCheck.push(new RegExp("(^|\\s)" + classes[k] + "(\\s|$)"));
for (var l=0, ll=elements.length; l<ll;l+=1)
{
node = elements[l];
match = false;
for (var m=0, ml=classesToCheck.length; m<ml; m+=1)
{
match = classesToCheck[m].test(node.className);
if (!match) break;
}
if (match) returnElements.push(node);
}
}
return returnElements;
}
Actualización:
Una nueva nota sobre esto. Desde entonces he vuelto a leer las notas sobre la implementación original, y ahora entiendo que mi código podría fallar en el caso de que el navegador existente tenga su propia implementación, porque las implementaciones predeterminadas devuelven una lista de nodos donde esto devuelve una matriz. Esto incluye los navegadores más recientes de Firefox y Safari, y Opera. La mayoría de las veces eso no importará, pero en algunas situaciones podría. Eso explica el ítem n. ° 2 de la lista anterior.
Lo que eso significa es que aunque mi código técnicamente funciona en todas partes, podría dar como resultado un comportamiento sutilmente diferente (leer: difícil de depurar) en diferentes lugares, y eso no es bueno. I debería solucionar esto también devolver una lista de nodos o reemplazar el método proporcionado para devolver una matriz (que es lo que hizo el original). Probablemente el primero sería más simple, pero este último sería mejor.
Sin embargo, está funcionando en este momento en el entorno de intranet local (prácticamente todos los IE), así que por el momento dejaré la solución como un ejercicio para el lector.
¿Por qué esto bajó su nombre? Esto está perfectamente bien para una solución de todo-JavaScript. –
De acuerdo. Parece haber un sesgo en el marco JS en SO hasta el punto en que las sugerencias de JavaScript puro son menospreciadas. Recomendar y señalar soluciones en frameworks están bien, pero también lo son las soluciones de JavaScript independientes. – AnthonyWJones
Predicando al coro, seguro. Me encanta usar un marco, pero el hecho es que no todos quieren usar uno o pueden hacerlo. Creo que algunos de los que usan frameworks no saben lo suficiente como para saber cómo hacerlo sin uno, entonces ven estas respuestas y las rechazan por ignorancia u orgullo o algo por el estilo. –