Al desarrollar una página web, en muchos casos necesitamos operar elementos con el mismo nombre de clase, es decir, elementos con la misma clase. Ayer tomé la prueba escrita y no respondí una pregunta relacionada:
JavaScript obtiene el nodo con la prueba de clase en la página
Así que recopilé información relevante y enumeré dos métodos que creo que son mejores. Las deficiencias también son necesarias. Espero que todos los critiquen y corrigan. Si tienes una mejor manera, espero que puedas compartirlo.
Solución1 Jeremy Keuth Solución
El tío Jeremy Keuth habló sobre el método GetElementsByClass en la tercera y cuarta sección del libro "JavaScript DOM Programming Art" (2ª edición) (Inglés: diseño de secuencias de comandos DOM con JavaScript y el modelo de objetos de documentos), y habló sobre cómo aplicar este método en los navegadores que no admiten esta propiedad (IE6, IE7 e IE8, vamos a los dos, vamos a los dos). Los extractos están aquí, y hay modificaciones en algunos lugares.
Se ha agregado un nuevo método a HTML5 DOM para permitirnos acceder a elementos a través del nombre de clase en el atributo de clase, que es: GetElmentsByClassName. Dado que el método es relativamente nuevo, algunas implementaciones de DOM aún no lo tienen, así que tenga cuidado al usarlo. Primero echemos un vistazo a lo que este método puede ayudarnos, y luego discutamos cómo usar este método de manera confiable.
Similar al método GetElmentsByTagName, GetElementsByClassName también solo acepta un parámetro, que es el nombre de clase:
La copia del código es la siguiente:
getElementsByClassName (clase)
El valor de retorno de este método también es similar a GetElementsByTagName, ambos son una matriz de elementos con el mismo nombre de clase. La siguiente línea de código devuelve una matriz que contiene todos los elementos del nombre de clase "Venta":
La copia del código es la siguiente:
document.getElementsByClassName ("Venta")
Use este método para encontrar elementos con múltiples nombres de clase. Para especificar múltiples nombres de clase, simplemente separe los nombres de clase con espacios en los parámetros de cadena. Por ejemplo, agregue la siguiente línea de código a la etiqueta <Script>:
La copia del código es la siguiente:
alerta (document.getElementsByClassName ("Venta importante"). Longitud);
Código completo
La copia del código es la siguiente:
<! Doctype html>
<html>
<Evista>
<meta charset = "utf-8">
<title> Lista de compras </title>
</ablo>
<Body>
<h1> Qué comprar </h1>
<p> No olvides comprar estas cosas. </p>
<ul id = "compra">
<li> un delgado de frijoles </li>
<li> queso </li>
<li> leche </li>
</ul>
<script>
alerta (document.getElementsByClassName ("Venta importante"). Longitud);
</script>
</body>
</html>
Verá un 1 en el cuadro de advertencia, lo que indica que solo un elemento coincide, porque solo un elemento tiene los nombres de clases "importantes" y de "venta". Tenga en cuenta que incluso en el atributo de clase de un elemento, el orden de los nombres de clase es "venta importante" en lugar de la "venta importante" especificada en el parámetro, aún coincidirá con el elemento. El orden real de los nombres de clase no solo no importa, sino que no importa incluso si los elementos tienen más nombres de clases. Al igual que el uso de GetElmentsBytagName, también puede usar GetElementsByClassName y GetElementByid en combinación. Si desea saber cuántos nombres de clases contienen elementos de la lista de pruebas en un elemento con compra de identificación, puede encontrar ese objeto específico primero y luego llamar a GetElementsByClassName:
La copia del código es la siguiente:
var compras = document.getElementById ("compra");
var ventas = compras.getElementsByClassName ("Venta");
De esta manera, la matriz de ventas contiene solo elementos con la clase de "ventas" ubicada en la lista de "compras". Ejecute la siguiente línea de código y verá que la matriz de ventas contiene dos artículos:
La copia del código es la siguiente:
alerta (sales.length);
Este método GetElmentsByClassName es muy útil, pero solo los navegadores más nuevos (Safari 3.1, Chorme, Firefox 3 y Opera 9.5 o superior) lo admiten. Para compensar esta deficiencia, los programadores de script DOM deben usar los métodos DOM existentes para implementar sus propios GetElementsByClassName, que es un poco como un regalo de la mayoría de edad. En la mayoría de los casos, su proceso de implementación es aproximadamente similar al siguiente GetElementsByClassName, que se puede aplicar a navegadores nuevos y antiguos.
La copia del código es la siguiente:
función getElementsByClassName (node, classname) {
if (node.getElementsByClassName) {
return node.getElementsByClassName (className);
}demás{
resultados var = [];
var elems = node.getElementsByTagName ("*");
para (var i = 0; i <elems.length; i ++) {
if (elems [i] .classname.indexof (classname)! =-1) {
Resultados [resultado.length] = Elems [i];
}
}
resultados de devolución;
}
}
La función GetElementsByClassName acepta dos parámetros. El primer nodo representa el punto de partida de búsqueda en el árbol DOM, y el segundo nombre de clase es el nombre de clase a buscar. Si ya existe la función GetElementsByClassName apropiada en el nodo entrante, entonces esta nueva función devuelve directamente la lista de nodos correspondiente. Si la función GetElementsByClassName no existe, la nueva función pasará a través de todas las etiquetas y buscará elementos con el nombre de clase correspondiente.
La desventaja de este método es que no se aplica a múltiples nombres de clase.
Si usa esta función para simular la operación anterior de obtener la lista de compras, puede escribirla así:
La copia del código es la siguiente:
var compras = document.getElementById ("compra");
var ventas = compras.getElementsByClassName (compras, "prueba");
console.log (ventas);
Por lo tanto, para resolver el problema al comienzo del artículo, el código utilizado es el siguiente:
La copia del código es la siguiente:
<! Doctype html>
<html>
<Evista>
<meta charset = "utf-8">
<title> Lista de compras </title>
</ablo>
<Body>
<h1> Qué comprar </h1>
<p> No olvides comprar estas cosas. </p>
<ul id = "compra">
<li> un delgado de frijoles </li>
<li> queso </li>
<li> leche </li>
</ul>
<script>
función getElementsByClassName (node, classname) {
if (node.getElementsByClassName) {
return node.getElementsByClassName (className);
}demás{
resultados var = [];
var elems = node.getElementsByTagName ("*");
para (var i = 0; i <elems.length; i ++) {
if (elems [i] .classname.indexof (classname)! =-1) {
Resultados [resultado.length] = Elems [i];
}
}
resultados de devolución;
}
}
var cuerpo = document.getElementsBytagName ("Body") [0];
var ventas = getElementsByClassName (cuerpo, "ventas");
console.log (ventas);
</script>
</body>
</html>
Solución2 Robert Nyman Solución
Hay muchas formas de buscar elementos DOM coincidentes, pero no muchos son verdaderamente eficientes. Una desventaja del método del tío Jeremy Keuth es que no se puede usar para múltiples nombres de clases. En 2008, Robert Nyman proporcionó su propia solución en el artículo The Ultimate GetElementsByClassName, Anno 2008. En 2005, el tío Robert ya le había dado su función GetElementsByClassName. En 2008, modificó algún código y agregó muchas funciones nuevas:
1. Si el navegador actual admite la función GetElementsByClassName, se llama la función nativa;
2. Si el navegador actual lo admite, use XPATH; // xiaofeiyu: una forma poderosa de localizar documentos XML construidos en el navegador, pero el soporte del navegador no está unificado
3. Admite la búsqueda de múltiples nombres de clase independientemente del orden;
4. Devuelve la matriz de nodo real, no un nodelista nativo. // Xiaofeiyu: El método nativo de GetElementsByClassName devuelve un objeto Nodelist, que es muy similar a una matriz, con propiedades de índice de longitud y número, pero no es una matriz, y no puede usar métodos exclusivos de pop y empuje, etc. En el código proporcionado por Robert, el objeto Nodelist se convierte en una matriz. Métodos donde los objetos nodelistas se pueden convertir en matrices:
La copia del código es la siguiente:
myList = array.prototype.slice.call (mynodelist)
Este es el método del tío Robert. No entiendo algunas de las cosas que aún tengo que entender. Lo actualizaré después de haberlos estudiado.
La copia del código es la siguiente:
/*
Desarrollado por Robert Nyman, http://www.robertnyman.com
Código/licencia: http://code.google.com/p/getelementsbyclassname/
*/
var getElementsByClassName = function (classname, tag, Elm) {
if (document.getElementsByClassName) {
getElementsByClassName = function (classname, tag, Elm) {
Elm = Elm || documento;
VAR Elements = Elm.getElementsByClassName (className),
NodeName = (etiqueta)? nuevo regexp ("// b" + etiqueta + "// b", "i"): nulo,
returnElements = [],
Actual;
para (var i = 0, il = Elements.length; i <il; i+= 1) {
actual = elementos [i];
if (! NodeName || NodeName.test (current.nodeName)) {
returnElements.push (actual);
}
}
devolver loselementos de retorno;
};
}
else if (document.evaluate) {
getElementsByClassName = function (classname, tag, Elm) {
etiqueta = etiqueta || "*";
Elm = Elm || documento;
classes var = classname.split (""),
ClassestOcheck = "",
xhtmlnamespace = "http://www.w3.org/1999/xhtml",
NamespaceResolver = (document.documentelement.namespaceuri === xhtmlnamespace)? xhtmlnamespace: nulo,
returnElements = [],
elementos,
nodo;
for (var j = 0, jl = classes.length; j <jl; j+= 1) {
ClassSecheck + = "[contiene (concat ('', @class, ''), '" + clases [j] + "')]";
}
intentar {
elements = document.evaluate (".//" + tag + classSecoCheck, Elm, NamespaceReSolver, 0, null);
}
Catch (e) {
elements = document.evaluate (".//" + tag + classSecoCheck, Elm, nulo, 0, nulo);
}
while ((node = elements.iterAntExt ())) {
returnElements.push (nodo);
}
devolver loselementos de retorno;
};
}
demás {
getElementsByClassName = function (classname, tag, Elm) {
etiqueta = etiqueta || "*";
Elm = Elm || documento;
classes var = classname.split (""),
classSecoCheck = [],
elements = (tag === "*" && elm.all)? Elm.all: Elm.getElementsBytagName (etiqueta),
Actual,
returnElements = [],
fósforo;
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) {
actual = elementos [l];
Match = false;
para (var m = 0, ml = classSecoCheck.length; m <ml; m+= 1) {
Match = ClassSecoCheck [m] .test (current.classname);
if (! Match) {
romper;
}
}
if (match) {
returnElements.push (actual);
}
}
devolver loselementos de retorno;
};
}
return getElementsByClassName (classname, tag, Elm);
};