WEBLEB
Inicio
Editora de código
Iniciar sesión
Pro
Español
English
Français
Español
Control deslizante de imágenes adaptable
2239
Andev.web
Abrir en el editor
Publica tu código
3
Recomendado
31 October 2023
Juego de Serpiente Simple
5 January 2025
Una página de inicio de lavanda
1 November 2024
Sitio web de portafolio HTML con menú lateral
HTML
Copy
CSS
Copy
*, *::after, *::before { margin: 0; padding: 0; box-sizing: border-box; } :root { --active-color: hsl(204 100 53); --bg-color: #e1e3e5; --icon-default: hsl(203 5 75); --icon-accent: hsl(203 15 98); --navigation-color: hsl(203 5 25 / 0.3); } body { min-block-size: 100vh; display: flex; justify-content: center; align-items: center; background-color: var(--bg-color); } .image-slider { display: flex; flex-flow: column; width: clamp(360px, 96vw, 830px); aspect-ratio: 16 / 9; min-height: 300px; overflow: hidden; border-radius: 8px; container-type: inline-size; contain: content; background-color: #0006; box-shadow: rgba(0, 0, 0, 0.2) 0px 1px 2px, rgba(0, 0, 0, 0.3) 0px 2px 4px, rgba(0, 0, 0, 0.25) 0px 4px 8px, rgba(0, 0, 0, 0.2) 0px 8px 16px, rgba(0, 0, 0, 0.15) 0px 16px 32px; } .slider__content { flex-grow: 1; display: flex; justify-content: space-between; } .slider-control--button { border: 0; background: 0; outline: 0; cursor: pointer; place-content: center; padding-inline: 3vw; z-index: 1; display: grid; } .icon { height: 2rem; width: 2rem; fill: var(--icon-default); border-radius: 50%; } .slider-control--button:where(:hover) { background-image: linear-gradient( to var(--position), #0000 0%, #0002, 80%, #0006 100% ); .icon { fill: var(--icon-accent); background: #0001; } } .slider-control--button:active { outline: 0.2em solid hsl(204 100 53); outline-offset: -0.5em; } .prev-button { --position: left; } .next-button { --position: right; } .image-display { position: fixed; inset: 0; } .slider-navigation { z-index: 10; display: grid; grid-auto-flow: column; grid-template-columns: repeat(6, 1fr); grid-auto-columns: 100%; gap: 1.25rem; padding: 1rem; place-content: center; background-color: var(--navigation-color); backdrop-filter: blur(6px); } .nav-button { display: grid; width: 100%; height: 100%; border-radius: 0.5em; overflow: hidden; align-items: center; justify-content: center; border: 0; aspect-ratio: 16 / 9; transition: filter 150ms linear, scale 266ms ease; } .thumbnail { display: block; max-width: 100%; width: 100%; object-fit: cover; height: 100%; } .nav-button[aria-selected="true"] { scale: 1.1; } .nav-button[aria-selected="true"], .nav-button:focus-visible { outline: 0.2em solid var(--active-color); outline-offset: 0.2em; } .nav-button[aria-selected="false"] { filter: opacity(0.7); } .nav-button[aria-selected="false"]:where(:hover, :focus-visible) { filter: opacity(1); } @container (max-width: 660px) { .nav-button:not(:has(img)) { background-color: rgb(241, 235, 232); } .slider-navigation { display: flex; justify-content: center; padding-block: 1.5em; } .nav-button { inline-size: 0.625rem; aspect-ratio: 1; border-radius: 50%; } .nav-button > .thumbnail { display: none; } .nav-button[aria-selected="true"] { background-color: black; scale: 1.5; } }
JS
Copy
class Slider { constructor(slider) { this.slider = slider; this.display = slider.querySelector(".image-display"); this.navButtons = Array.from(slider.querySelectorAll(".nav-button")); this.prevButton = slider.querySelector(".prev-button"); this.nextButton = slider.querySelector(".next-button"); this.sliderNavigation = slider.querySelector(".slider-navigation"); this.currentSlideIndex = 0; this.preloadedImages = {}; this.initialize(); } initialize() { this.setupSlider(); this.preloadImages(); this.eventListeners(); } setupSlider() { this.showSlide(this.currentSlideIndex); } showSlide(index) { this.currentSlideIndex = index; const navButtonImg = this.navButtons[ this.currentSlideIndex ].querySelector("img"); if (navButtonImg) { const imgClone = navButtonImg.cloneNode(); this.display.replaceChildren(imgClone); } this.updateNavButtons(); } updateNavButtons() { this.navButtons.forEach((button, buttonIndex) => { const isSelected = buttonIndex === this.currentSlideIndex; button.setAttribute("aria-selected", isSelected); if (isSelected) button.focus(); }); } preloadImages() { this.navButtons.forEach((button) => { const imgElement = button.querySelector("img"); if (imgElement) { const imgSrc = imgElement.src; if (!this.preloadedImages[imgSrc]) { this.preloadedImages[imgSrc] = new Image(); this.preloadedImages[imgSrc].src = imgSrc; } } }); } eventListeners() { document.addEventListener("keydown", (event) => { this.handleAction(event.key); }); this.sliderNavigation.addEventListener("click", (event) => { const targetButton = event.target.closest(".nav-button"); const index = targetButton ? this.navButtons.indexOf(targetButton) : -1; if (index !== -1) { this.showSlide(index); } }); this.prevButton.addEventListener("click", () => this.handleAction("prev") ); this.nextButton.addEventListener("click", () => this.handleAction("next") ); } handleAction(action) { if (action === "Home") { this.currentSlideIndex = 0; } else if (action === "End") { this.currentSlideIndex = this.navButtons.length - 1; } else if (action === "ArrowRight" || action === "next") { this.currentSlideIndex = (this.currentSlideIndex + 1) % this.navButtons.length; } else if (action === "ArrowLeft" || action === "prev") { this.currentSlideIndex = (this.currentSlideIndex - 1 + this.navButtons.length) % this.navButtons.length; } this.showSlide(this.currentSlideIndex); } } const ImageSlider = new Slider(document.querySelector(".image-slider"));