Bienvenidos sean a este post, hoy veremos un tema que mencionamos superficialmente.
En el post anterior establecimos la base de nuestro proyecto y las acciones que iba a tener pero lo dejamos con un fallo, al momento de agregar mas fotos no eran capturados por los eventos cuando pasamos el cursor sobre las mismas, para solucionar esto vamos a volver a usar a la funcion closest que usamos en este post, dado que esta funcion nos buscara todos los elementos que le informemos, para entender este concepto vamos a tomar el ejemplo que vimos en el post anterior, en caso de no tenerlo les dejo un link para descargarlo:
El contenido deberan extraerlo en un servidor web porque como usa Ajax no podran utilizarlo de manerra local, en caso de no tener uno les recomiendo estos dos posts:
En este les comento como crear un pc virtual e instalarle un linux debian, y el siguiente post:
Este es para instalar un Apache, el PHP y mariadb en un servidor debian, esto se los recomiendo asi porque solo necesita 1 GB de RAM, muy poco espacio en disco y cuando no lo necesiten mas simplemte borran la virtual y listo, si ya agregaron los archivos en el servidor nuestro primer paso sera ir al archivo codigo.js y modificaremos este bloque de codigo:
$(document).ready(function() {
$('div.foto').on('mouseenter mouseleave', function(ev) {
var $detalles = $(this).find('.detalles');
if (ev.type == 'mouseenter') {
$detalles.fadeTo('fast',0.7);
} else {
$detalles.fadeOut('fast');
}
});
});
De la siguiente manera:
$(document).ready(function() {
$('#galeria').on('mouseover mouseout', function(ev) {
var $destino = $(ev.target).closest('div.foto');
var $detalles = $destino.find('.detalles');
var $relacion = $(ev.relatedTarget).closest('div.foto');
if (ev.type == 'mouseover' && $destino.length) {
$detalles.fadeTo('fast',0.7);
} else if (ev.type == 'mouseout' && $relacion.length) {
$detalles.fadeOut('fast');
}
});
});
En este caso cambiamos los eventos a monitorear, despues la complicamos un poco porque primero definimos un objeto llamado destino en este emplearemos a closest para que tome todo los elementos relacionados a div.foto, observen que usamos la propiedad target para indicar cual es el evento que estamos monitoreando, la siguiente sera para almacenar cual seran los de detalles que mostraremos u ocultaremos, por ultimo tendremos un objeto donde almacenaremos tambien los eventos del destino relacionado y de vuelta usamos a closest para obtener todos los elementos, despues modificamos el condicional no solamente cambiamos los eventos sino que le agregamos la verificacion de que tanto destino como relacion tenga un dato interno, despues seguiremos usandolo para mostrar y esconder tal como antes, veamos como funciona ahora
Como pueden ver ahora si se pasaron los eventos a los nuevos elementos pero no funciona como lo hacia anteriormente, para ello volveremos a tomar el bloque de codigo anterior y lo modificaremos de la siguiente manera:
$(document).ready(function() {
$('#galeria').on('mouseenter mouseleave', 'div.foto', function(ev) {
var $detalles = $(this).find('.detalles');
if (ev.type == 'mouseenter') {
$detalles.fadeTo('fast',0.7);
} else {
$detalles.fadeOut('fast');
}
});
});
Este es mas parecido al original donde volvemos a usar al div identificado como galeria, volvemos a usar los eventos orginales (mouseenter y mouseleave, pero ahora antes del evento le pasamos el destino donde estan todos los elementos que usaremos para estos eventos, y en este caso el metodo on automaticamente lo delegara a dicho elemento mediante this, por lo tanto siempre estara monitoreando a cada elemento, despues en detalles buscamos detalles y por medio del condicional original chequeamos si el mouse entro y lo mostramos en caso contrario esconde los mismos, veamos como trabaja ahora
Ahora no solo hemos mejorado el codigo sino que tambien ha vuelto a trabajar como antes y a su vez baja los eventos a los nuevos elementos que agregamos, pero esto tambien podemos cambiarle su scope o alcance, por ejemplo tomemos el codigo anterior y modifiquemoslo de la siguiente manera:
$(document).ready(function() {
$(document).on('mouseenter mouseleave', 'div.foto', function(ev) {
var $detalles = $(this).find('.detalles');
if (ev.type == 'mouseenter') {
$detalles.fadeTo('fast',0.7);
} else {
$detalles.fadeOut('fast');
}
});
});
En este caso le quitamos el id especifico como es galeria y se lo aplicamos a toda la pagina o document, el resto sigue de la misma forma porque galeria es parte de document y al buscarlo lo encontrara sin inconvenientes, pero si usamos a document podemos hacer que no dependa del metodo ready dado que el document se carga siempre primero por lo tanto podemos cambiar el codigo anterior de la siguiente forma:
(function($) {
$(document).on('mouseenter mouseleave', 'div.foto', function(ev) {
var $detalles = $(this).find('.detalles');
if (ev.type == 'mouseenter') {
$detalles.fadeTo('fast',0.7);
} else {
$detalles.fadeOut('fast');
}
});
})(jQuery);
En este caso lo aplicamos al namespace jQuery, tal como hicimos con los plug-in, y no este a la espera de que la pagina este lista mejorando mucho mas la respuesta de la lectura de eventos, un consejo que les puedo dar es que este bloque lo ubiquen al comienzo del archivo por delante de los otros bloques de codigo para evitar problemas, y este al igual que los plug-in podemos tenerlo en un archivo aparte pero por un tema de practicidad lo dejo en el mismo, en estos ultimos dos codigos la pagina deberia funcionar de la misma forma, antes de finalizar les dejo todos los archivos del ejemplo y los codigos finales de este post:
En resumen, hoy hemos visto como delegar eventos, primero con el caso de closest y luego por la propiedad de delegacion que posee el metodo on, despues hablamos un poco del scope de la delegacion y desde donde podemos rastrearlo y por ultimo como no necesariamente debemos esperar a que este cargada para trabajarla, espero les haya sido util sigueme en tumblr, Twitter o Facebook para recibir una notificacion cada vez que subo un nuevo post en este blog, nos vemos en el proximo post.


Donación
Es para mantenimento del sitio, gracias!
$1.50
