旋转木马幻灯片,具有无限循环功能。
旋转木马幻灯片,具有无限循环功能。
更新:07/13
我找到了一种更好的方法来解决使用JS属性cloneNode
实现无限滚动的问题,并使用它来在克隆的幻灯片前面和后面创建无限效果。
我还学会了一种更高效的编写大量代码的方法,并且成功解决了transitionend
导致的事件冒泡问题。
所以,还有两个问题:
我仍然无法将圆点与幻灯片对应起来。克隆的幻灯片似乎扰乱了幻灯片数组,并且使用data-
设置圆点对我来说不起作用。
我使用变换来移动幻灯片容器来创建幻灯片秀,但是如果我调整窗口大小,幻灯片容器的溢出就会变得可见。查看www.ramtrucks.com,我注意到在调整窗口大小时,幻灯片秀上的变换和宽度属性会动态变化。我研究了JS的调整大小事件,但是它们中的没有一个似乎与我的代码合作,我认为这是因为我使用了flexbox。所以我需要同时调整大小并更改flex属性(我想是这样)。
这是我目前的进展:
// ----- 幻灯片声明 ----- // const slideShowContainer = document.querySelector('.slideShow'); const slidesContainer = document.querySelector('.slidesContainer'); const rightBtn = document.querySelector('#slideRight'); const leftBtn = document.querySelector('#slideLeft'); const slideShowInterval = 10000; let slides = document.querySelectorAll('.slideCard'); let index = 1; let currentSlide; let dots; const firstClone = slides[0].cloneNode(true); const lastClone = slides[slides.length - 1].cloneNode(true); firstClone.id = 'firstClone' lastClone.id = 'lastClone' slidesContainer.append(firstClone); slidesContainer.prepend(lastClone); const slideWidth = slides[index].clientWidth; slidesContainer.style.transform = `translateX(${-slideWidth * index}px)`; // -------------------- // // ----- 克隆交换 ----- // const slideCollection = () => document.querySelectorAll('.slideCard'); slidesContainer.addEventListener('transitionend', () => { slides = slideCollection(); if (slides[index].id === firstClone.id) { index = 1; slidesContainer.style.transition = 'none'; slidesContainer.style.transform = 'translateX(' + (-slideWidth * index) + 'px)'; } slides = slideCollection(); if (slides[index].id === lastClone.id) { index = slides.length - 2; slidesContainer.style.transition = 'none'; slidesContainer.style.transform = 'translateX(' + (-slideWidth * index) + 'px)'; } }); // -------------------- // // ----- 导航按钮 ----- // const moveRight = () => { slides = slideCollection(); if (index >= slides.length - 1) return; index++; slidesContainer.style.transition = 'transform 0.4s ease-in-out'; slidesContainer.style.transform = 'translateX(' + (-slideWidth * index) + 'px)'; closeDisclosure(); } const moveLeft = () => { slides = slideCollection(); if (index <= 0) return; index--; slidesContainer.style.transition = 'transform 0.4s ease-in-out'; slidesContainer.style.transform = 'translateX(' + (-slideWidth * index) + 'px)'; closeDisclosure(); } rightBtn.addEventListener('click', moveRight); leftBtn.addEventListener('click', moveLeft); // -------------------- // // ----- 选择圆点 ----- // const selectDotsGroup = () => document.querySelector('slideNumberDots'); const slideSelect = () => document.querySelectorAll('.slideDot'); const setCurrentSlide = () => { slideDots = slideSelect(); slideDots[index - 1].classList.add('selectedSlide'); }; setCurrentSlide(); // -------------------- // // ----- 幻灯片自动播放 ----- // const autoplay = () => { currentSlide = setInterval(() => { moveRight(); closeDisclosure(); }, slideShowInterval); } slidesContainer.addEventListener('mouseenter', () => { clearInterval(currentSlide); }) slidesContainer.addEventListener('mouseleave', autoplay); autoplay(); // -------------------- // // ----- 披露窗口脚本 ----- // // 打开披露窗口 let discBtn = document.getElementsByClassName("disclosurePrompt"); let disc; for (disc = 0; disc < discBtn.length - 0; disc++) { discBtn[disc].addEventListener("click", function() { this.nextElementSibling.classList.add("discVisible"); }); } // 关闭披露窗口 let closeBtn = document.getElementsByClassName("fa-times"); let close; for (close = 0; close < closeBtn.length - 0; close++) { closeBtn[close].addEventListener("click", function() { var slideDiscWindow = document.querySelectorAll(".discVisible"); [].forEach.call(slideDiscWindow, function(el) { el.classList.remove("discVisible"); }); }); } // 在幻灯片更改时关闭披露窗口 function closeDisclosure() { var slideDiscWindow = document.querySelectorAll(".discVisible"); [].forEach.call(slideDiscWindow, function(el) { el.classList.remove("discVisible"); }); } // -------------------- //
*, *::before, *::after { margin: 0; padding: 0; box-sizing: border-box; } body { background-color: darkgrey; } html { font-size: 16px; } .slideShowWrapper { display: flex; flex-direction: row; position: relative; width: 100%; height: 40vw; margin: 0; padding: 0; overflow: hidden; } /* 开始幻灯片布局 */ .slideShow { display: flex; justify-content: flex-start; flex-direction: row; position: relative; width: 100vw; height: 40vw; margin: 0 auto; padding: 0; overflow: hidden; } .slidesContainer { display: flex; flex: 1 0 100%; flex-direction: row; width: 100vw; height: 40vw; margin: 0; padding: 0; } .slideCard { display: flex; flex-direction: row; flex: 1 0 100%; position: relative; height: 40vw; width: 100vw; min-width: 100%; margin: 0; padding: 0; background-color: transparent; } .fa-chevron-right { display: block; opacity: 0; font-size: 2.3vw; position: absolute; top: 50%; right: 0; color: white; margin: 0 5%; padding: 0; width: auto; height: auto; z-index: 1; background-color: transparent; cursor: pointer; transform-origin: center; transition: transform 0.15s linear, opacity 0.15s linear; } .fa-chevron-left { display: block; opacity: 0; font-size: 2.3vw; position: absolute; top: 50%; left: 0; color: white; margin: 0 5%; padding: 0; width: auto; height: auto; z-index: 1; background-color: transparent; cursor: pointer; transition: transform 0.15s linear, opacity 0.15s linear; } .fa-chevron-right:hover { transform: scale(1.2); } .fa-chevron-left:hover { transform: scale(1.2); } .slideShowWrapper:hover .fa-chevron-right { opacity: 1; } .slideShowWrapper:hover .fa-chevron-left { opacity: 1; } .slideNumberDots { display: flex; flex-direction: row; justify-content: center; bottom: 0%; gap: 0.8vw; position: absolute; width: 100%; z-index: 1; margin: 0 auto; padding: 1vw; background-color: transparent; pointer-events: none; } .slideDot { display: flex; height: 0.8vw; width: 0.8vw; border-radius: 50%; border: 0px solid rgb(27, 27, 27); margin: 0; padding: 0; background-color: white; transform-origin: center; transition: transform 0.2s linear, background-color 0.2s linear; pointer-events: all; } .slideDot:hover { background-color: #1c69d3; transform-origin: center; transform: scale(1.3); cursor: pointer; } .slideDot.selectedSlide { background-color: #1c69d3; transform: scale(1.2); transform-origin: center; transition: color, transform 0.3s linear; outline: 0.15vw solid black; border-radius: 50%; } .disclosurePrompt { display: flex; font-family: BMWTypeNext Latin TT, 'DDC Heading Font Face', 'Helvetica Neue', Helvetica, Arial, sans-serif; position: absolute; color: white; font-size: 0.8vw; font-weight: 400; line-height: 1.25; width: fit-content; height: fit-content; top: 95%; left: 5%; cursor: pointer; z-index: 2; user-select: none; outline: 1px transparent; text-decoration: underline; } .disclosurePrompt:hover { color: #e4e4e4; } .disclosurePrompt:focus { color: #e4e4e4; } .disclosureContainer { visibility: hidden; width: 90vw; height: auto; outline: 1px solid black; background-color: rgba(0, 0, 0, 0.95); position: absolute; margin: 0 auto; bottom: 5%; left: 5%; opacity: 0; z-index: 10; transition: opacity, top, 0.3s linear; } .disclosureContainer.discVisible { visibility: visible; bottom: 10.5%; opacity: 1; } .disclosureText { font-family: BMWTypeNext Latin TT, 'DDC Heading Font Face', 'Helvetica Neue', Helvetica, Arial, sans-serif; color: white; line-height: clamp(0.7rem, -0.6rem + 3vw, 0.9rem); font-size: clamp(0.5rem, -0.875rem + 3vw, 0.7rem); display: block; margin: 0 auto; padding: 1.5rem 0.5rem 0.5rem 0.5rem; text-align: justify; } .fa-times { display: block; color: white; font-size: 0.8em; position: absolute; left: 0; top: 0; z-index: 12; padding: 0.5rem 0.5rem; transition: all 0.2s linear; cursor: pointer; } .fa-times:hover { color: #1c69d3; transition: all 0.2s linear; } /* 结束幻灯片布局 */ /* 开始图片 */ .bmw2series { content: url("https://i.imgur.com/MABHqGy.jpg"); width: 100%; height: 100%; object-fit: cover; user-select: none; } .bmw3series { content: url("https://i.imgur.com/Ggy6iNU.jpg"); width: 100%; height: 100%; object-fit: cover; user-select: none; } .bmwX3 { content: url("https://i.imgur.com/ucYCFcu.jpg"); width: 100%; height: 100%; object-fit: cover; user-select: none; } .bmwiX { content: url("https://i.imgur.com/bQhvuOY.jpg"); width: 100%; height: 100%; object-fit: cover; user-select: none; } .bmw5series { content: url("https://i.imgur.com/sLYH9Gy.jpg"); width: 100%; height: 100%; object-fit: cover; user-select: none; } .bmwPreOwned { content: url("https://i.imgur.com/kuOWIEJ.jpg"); width: 100%; height: 100%; object-fit: cover; user-select: none; }