Cómo crear una presentación de diapositivas simple a pantalla completa con solo JavaScript
Spanish (Español) translation by Carlos (you can also view the original English article)
En este tutorial aprenderás a crear una presentación de diapositivas a pantalla completa con JavaScript simple. Para crearla, usaremos varios trucos de front-end distintos. Como un beneficio adicional, iremos un paso más allá y personalizaremos la apariencia del cursor mientras pasamos el puntero (hover) encima del pase de diapositivas.
Como es habitual, para tener una idea inicial de lo que vamos a crear, mira la demostración relacionada en CodePen (revisa la versión más grande para una mejor experiencia):
Nota: En este tutorial no se analizará cómo hacer que la presentación de diapositivas sea más accesible (por ejemplo, los botones). Nos centraremos principalmente en CSS y JavaScript.
1. Inicia con el marcado de la página
Para crear la presentación de diapositivas, necesitaremos un elemento con la clase slideshow
. Dentro, colocaremos
una lista de diapositivas junto con las flechas de navegación.
Cada diapositiva contendrá una imagen de fondo. Naturalmente, si así lo deseas, puedes añadir contenido adicional.
Por defecto, aparecerá la primera diapositiva. Pero podemos configurar ese comportamiento adjuntando la clase is-active
a la diapositiva deseada.
Aquí está el marcado que se requiere:
<div class="slideshow"> <ul class="slides"> <li class="slide is-active"> <div class="cover" style="background-image: url(IMG_SRC);"></div> </li> <li class="slide"> <div class="cover" style="background-image: url(IMG_SRC);"></div> </li> <li class="slide"> <div class="cover" style="background-image: url(IMG_SRC);"></div> </li> </ul> <div class="arrows"> <button class="arrow arrow-prev"> <span></span> </button> <button class="arrow arrow-next"> <span></span> </button> </div> </div> <main>...</main>
2. Define los estilos
Con el marcado preparado, continuaremos con los estilos principales de nuestra presentación de diapositivas.
Apilando las diapositivas
De forma predeterminada, todas las diapositivas se apilan sobre otra. Todas estarán ocultas, excepto la diapositiva activa.
Para apilar las imágenes, aprovecharemos CSS Grid. De hecho, ya he cubierto esta técnica y sus ventajas en comparación con el posicionamiento tradicional en un tutorial reciente.
Aquí están los estilos asociados:
.slideshow .slides { display: grid; } .slideshow .slide { grid-column: 1; grid-row: 1; opacity: 0; transition: opacity 0.4s; } .slideshow .slide.is-active { opacity: 1; }
Cada div
dentro de una diapositiva recibirá la clase cover
. Esto convertirá su imagen de fondo en una imagen de fondo a pantalla completa:
.cover { background-size: cover; background-repeat: no-repeat; background-position: center; height: 100vh; }
Navegación
Los botones de navegación estarán posicionados de manera absoluta dentro de la presentación de diapositivas. Cada uno de los botones debe cubrir la mitad del ancho de la presentación de diapositivas, y su altura debe ser igual a la altura de esta.



Al principio, todos los botones estarán ocultos. Pero, cuando empecemos a mover el cursor dentro de la presentación de diapositivas, aparecerá el botón correspondiente según la posición del mouse.
Cada span
dentro de un botón tendrá una flecha (izquierda o derecha) como imagen de fondo.

De forma predeterminada, el color de estas flechas será negro. No obstante, a medida que movemos el cursor dentro de la presentación de diapositivas, su color debería cambiar y crear un contraste con las imágenes de la diapositiva. El truco para crear este efecto es añadir mix-blend-mode: difference
(o exclusion
) y filter: invert(1)
a los span
s.

Para aprender más acerca de cómo funcionan los diversos modos de mezcla en CSS (y qué alternativas están disponibles para ti) mira esta guía de modos de fusión de Jonathan Cutrell:
Sigamos adelante, los estilos para la navegación están a continuación:
.slideshow { cursor: none; } .slideshow .arrows { position: absolute; top: 0; left: 0; display: flex; width: 100%; height: 100%; overflow: hidden; } .slideshow .arrows .arrow { position: relative; width: 50%; cursor: inherit; visibility: hidden; overflow: inherit; } .slideshow .arrows .is-visible { visibility: visible; } .slideshow .arrows span { position: absolute; width: 72px; height: 72px; background-size: 72px 72px; mix-blend-mode: difference; filter: invert(1); } .slideshow .arrow-prev span { background-image: url(slider-prev-arrow.svg); } .slideshow .arrow-next span { background-image: url(slider-next-arrow.svg); }
3. Añade el JavaScript
¡Ahora añadamos interactividad a nuestra presentación de diapositivas!
Para este ejemplo, la presentación de diapositivas tendrá tres opciones predeterminadas que podemos personalizar especificando los atributos personalizados asociados:
Opción | Valor predeterminado | Descripción |
---|---|---|
autoplay | false | Hace que la reproducción de la presentación sea automática. |
autoplay-interval | 4000 | El tiempo del intervalo entre los cambios de diapositivas en milisegundos. |
stop-autoplay-on-hover | false | Detener el modo de reproducción automática al pasar el puntero del mouse (hover). |
Variables
Antes de profundizar en estas opciones, como primer paso, definiremos un conjunto de variables que usaremos más tarde:
const slideshow = document.querySelector(".slideshow"); const list = document.querySelector(".slideshow .slides"); const btns = document.querySelectorAll(".slideshow .arrows .arrow"); const prevBtn = document.querySelector(".slideshow .arrow-prev"); const prevBtnChild = document.querySelector(".slideshow .arrow-prev span"); const nextBtn = document.querySelector(".slideshow .arrow-next"); const nextBtnChild = document.querySelector(".slideshow .arrow-next span"); const main = document.querySelector("main"); const autoplayInterval = parseInt(slideshow.dataset.autoplayInterval) || 4000; const isActive = "is-active"; const isVisible = "is-visible"; let intervalID;
Inicializando las cosas
Cuando todos los recursos de la página estén listos, llamaremos a la función init
.
window.addEventListener("load", init);
Esta función activará cuatro subfunciones:
function init() { changeSlide(); autoPlay(); stopAutoPlayOnHover(); customizeArrows(); }
Como veremos en un momento, cada una de estas funciones cumplirá una determinada tarea.
El bucle a través de las diapositivas
La función changeSlide
se encargará de enlazar las diapositivas.
Cada vez que se haga clic en un botón, realizaremos las siguientes acciones:
- Tomar una copia de la diapositiva actualmente activa.
- Eliminar la clase
is-active
de la diapositiva activa. - Comprobar en qué botón se ha hecho clic. Si ese es el siguiente botón, añadiremos la clase
is-active
a la diapositiva que sigue inmediatamente a la diapositiva activa. Si no existe tal diapositiva, la primera diapositiva recibirá esta clase. - Por otra parte, si se hace clic en el botón anterior, añadiremos la clase
is-active
a la diapositiva anterior de la diapositiva activa. Si no existe tal diapositiva, la última diapositiva recibirá esta clase.
Aquí está la firma de esta función:
// variables here function changeSlide() { for (const btn of btns) { btn.addEventListener("click", e => { // 1 const activeSlide = document.querySelector(".slide.is-active"); // 2 activeSlide.classList.remove(isActive); // 3 if (e.currentTarget === nextBtn) { activeSlide.nextElementSibling ? activeSlide.nextElementSibling.classList.add(isActive) : list.firstElementChild.classList.add(isActive); } else { // 4 activeSlide.previousElementSibling ? activeSlide.previousElementSibling.classList.add(isActive) : list.lastElementChild.classList.add(isActive); } }); } }
Reproducción automática
La función autoplay
se encargará de activar el modo de reproducción automática.
De forma predeterminada, tenemos que recorrer las diapositivas manualmente.
Para activar la reproducción automática, añadiremos el atributo data-autoplay="true"
a la presentación de diapositivas.
También podemos ajustar el tiempo del intervalo del cambio entre diapositivas definiendo data-autoplay interval="number"
(el valor predeterminado es 4000ms) como un segundo atributo, de esta manera:
<div class="slideshow" data-autoplay="true" data-autoplay-interval="6000"> ... </div>
Aquí está la firma de esta función:
// variables here function autoPlay() { if (slideshow.dataset.autoplay === "true") { intervalID = setInterval(() => { nextBtn.click(); }, autoplayInterval); } }
Detener la reproducción automática
La función stopAutoplayOnHover
será responsable de deshabilitar el modo de reproducción automática al pasar el puntero (hover) por la presentación de diapositivas.
Para habilitar esta funcionalidad, pasaremos el atributo data-stop-autoplay-on-hover="true"
a la presentación de
diapositivas, así:
<div class="slideshow" data-stop-autoplay-on-hover="true"> ... </div>
Aquí está la firma de esta función:
// variables here function stopAutoPlayOnHover() { if ( slideshow.dataset.autoplay === "true" && slideshow.dataset.stopAutoplayOnHover === "true" ) { slideshow.addEventListener("mouseenter", () => { clearInterval(intervalID); }); // touch devices slideshow.addEventListener("touchstart", () => { clearInterval(intervalID); }); } }
Personalizando las flechas
La función customizeArrows
será responsable de manejar la
visibilidad de los botones de navegación y la posición de sus span
s.
Como lo comentamos antes, los botones de navegación estarán ocultos al principio.
A medida que movamos el ratón dentro de la presentación de diapositivas, únicamente aparecerá una de ellas a la vez, dependiendo de la posición del ratón. La posición de su elemento span
también dependerá de las coordenadas del puntero del ratón.
Tan pronto como salgamos de la presentación, los botones se volverán a ocultar.
Para cumplir estos requisitos en distintas pantallas/dispositivos, usaremos dos eventos del mouse junto con dos eventos táctiles.
Aquí está el código que implementa esta funcionalidad:
// variables here function customizeArrows() { slideshow.addEventListener("mousemove", mousemoveHandler); slideshow.addEventListener("touchmove", mousemoveHandler); slideshow.addEventListener("mouseleave", mouseleaveHandler); main.addEventListener("touchstart", mouseleaveHandler); } function mousemoveHandler(e) { const width = this.offsetWidth; const xPos = e.pageX; const yPos = e.pageY; const xPos2 = e.pageX - nextBtn.offsetLeft - nextBtnChild.offsetWidth; if (xPos > width / 2) { prevBtn.classList.remove(isVisible); nextBtn.classList.add(isVisible); nextBtnChild.style.left = `${xPos2}px`; nextBtnChild.style.top = `${yPos}px`; } else { nextBtn.classList.remove(isVisible); prevBtn.classList.add(isVisible); prevBtnChild.style.left = `${xPos}px`; prevBtnChild.style.top = `${yPos}px`; } } function mouseleaveHandler() { prevBtn.classList.remove(isVisible); nextBtn.classList.remove(isVisible); }
Conclusión
¡Eso es todo, amigos! En este tutorial, logramos implementar una presentación de diapositivas flexible a pantalla completa escribiendo código JavaScript puro. ¡Esperemos que hayas disfrutado de este viaje y hayas adquirido nuevos conocimientos!
Aquí hay un recordatorio de lo que hemos creado:
Los siguientes pasos
Hay tantas cosas que puedes hacer para mejorar la funcionalidad de esta presentación de diapositivas. Aquí tienes algunas ideas:
- Añadir soporte para deslizamiento y navegación mediante el teclado. Como punto de partida, puedes mirar este tutorial.
- Por el momento, las diapositivas aparecen con una animación de desvanecimiento. Puedes crear otros modos de animación como deslizamiento y escala.
- Hacer que la presentación de diapositivas emita eventos personalizados cuando aparezca una nueva diapositiva.
- Hacer el código más reutilizable y sólido. Quizá desees utilizar Prototypal inheritance, ES6 classes u otro patrón de diseño de JavaScript.
- Implementar una posibilidad alternativa para los navegadores que no admiten efectos CSS filter (por ejemplo, algunas versiones de Microsoft Edge) para las flechas de navegación.
Como siempre, ¡muchas gracias por leer!
Aprende más acerca de las presentaciones de diapositivas con JavaScript
Revisa estos tutoriales para que aprendas más sobre cómo crear potentes presentaciones de diapositivas con JavaScript:
- Selectores CSSCómo crear una simple presentación de diapositivas con el truco checkbox de CSSGeorge Martsoukos
- jQueryCómo crear un carrusel deslizante responsivo a pantalla completa con Owl.jsGeorge Martsoukos
- jQueryCómo crear una galería de imágenes atractiva y responsiva con slick.jsGeorge Martsoukos