Actualmente estoy tratando de escribir un JavaScript para obtener el atributo de la clase que se ha hecho clic. Sé que para hacer esto de la manera correcta, debo utilizar un oyente de eventos. Mi código es el siguiente:
var classname = document.getElementsByClassName("classname");
var myFunction = function() {
var attribute = this.getAttribute("data-myattribute");
alert(attribute);
};
classname.addEventListener('click', myFunction(), false);
Esperaba obtener un cuadro de alerta cada vez que hiciera clic en una de las clases para indicarme el atributo, pero lamentablemente esto no funciona. ¿Alguien puede ayudar, por favor?
(Nota - Puedo hacer esto fácilmente en jQuery
pero NO me gustaría usarlo)
Esto debería funcionar. getElementsByClassName
devuelve un array objeto tipo array(ver edición) de los elementos que coinciden con los criterios.
var classname = document.getElementsByClassName("classname");
var myFunction = function() {
var attribute = this.getAttribute("data-myattribute");
alert(attribute);
};
for (var i = 0; i < classname.length; i++) {
classname[i].addEventListener('click', myFunction, false);
}
jQuery hace la parte de bucle para usted, que tiene que hacer en JavaScript llano.
Si usted tiene ES6 apoyo puede reemplazar su última línea con:
Array.from(classname).forEach(function(element) {
element.addEventListener('click', myFunction);
});
Nota: Los navegadores más antiguos (como IE6, IE7, IE8) no soportan getElementsByClassName
y por tanto devuelven undefined
.
EDIT : Corrección
El comando getElementsByClassName
no devuelve un array, sino un HTMLCollection en la mayoría, o un NodeList en algunos navegadores (Mozilla ref). Ambos tipos son similares a los arrays, (lo que significa que tienen una propiedad de longitud y que se puede acceder a los objetos a través de su índice), pero no son estrictamente un array o heredan de un array. (lo que significa que otros métodos que se pueden realizar en un Array no se pueden realizar en estos tipos)
Gracias al usuario @Nemo por señalar esto y hacerme indagar para entenderlo bien.
Esto fue editado para permitir que los hijos de la clase de destino activen los eventos. Ver la parte inferior de la respuesta para más detalles.
Una respuesta alternativa para añadir un receptor de eventos a una clase en la que se añaden y eliminan elementos con frecuencia. Esto se inspira en la función on
de jQuery, donde se puede pasar un selector para un elemento hijo en el que se escucha el evento.
var base = document.querySelector('#base'); // the container for the variable content
var selector = '.card'; // any css selector for children
base.addEventListener('click', function(event) {
// find the closest parent of the event target that
// matches the selector
var closest = event.target.closest(selector);
if (closest && base.contains(closest)) {
// handle class event
}
});
Fiddle:
Esto escuchará los clics en los hijos del elemento base
y si el objetivo de un clic tiene un padre que coincide con el selector, el evento de la clase será manejado. Puedes añadir y eliminar elementos como quieras sin tener que añadir más escuchas de clics a los elementos individuales. Esto los atrapará a todos, incluso a los elementos añadidos después de que se haya añadido este escuchador, al igual que la funcionalidad de jQuery (que imagino que es algo similar bajo el capó).
Esto depende de la propagación de los eventos, por lo que si se stopPropagation
en el evento en otro lugar, esto puede no funcionar. Además, la función closest
tiene algunos problemas de compatibilidad con IE aparentemente (¿qué no?).
Esto podría convertirse en una función si necesitas hacer este tipo de acción escuchando repetidamente, como
function addChildEventListener(base, eventName, selector, handler) {
base.addEventListener(eventName, function(event) {
var closest = event.target.closest(selector);
if (closest && base.contains(closest)) {
// passes the event to the handler and sets `this`
// in the handler as the closest parent matching the
// selector from the target element of the event
handler.call(closest, event);
}
});
}
=========================================
EDIT: Este post utilizaba originalmente la función matches
para los elementos del DOM en el objetivo del evento, pero esto restringía los objetivos de los eventos a la clase directa solamente. Se ha actualizado para utilizar la función closest
en su lugar, lo que permite que los eventos en los hijos de la clase deseada para desencadenar los eventos también. El código original de matches
se puede encontrar en el fiddle original:
https://jsfiddle.net/u6oje7af/23/
Puedes utilizar el código que aparece a continuación:
document.body.addEventListener('click', function (evt) {
if (evt.target.className === 'databox') {
alert(this)
}
}, false);