在本教程 中,您将学习如何使用纯 javascript 创建响应式全屏幻灯片。为了构建它,我们将通过几个不同的前端技巧。作为奖励,当我们将鼠标悬停在幻灯片上时,我们将更进一步并自定义光标的外观。
像往常一样,要初步了解我们将要构建的内容,请查看相关的 CodePen 演示(查看 更大的版本 以获得更好的体验):
See the Pen How to Build a Simple Full-Screen Slideshow With Vanilla JavaScript by Envato Tuts+ (@tutsplus) on CodePen.
信息本教程不会讨论如何使幻灯片更易于访问(例如按钮)。我们将主要关注 css 和 JavaScript。
1. 从页面标记开始
要创建幻灯片,我们需要一个带有slideshow类的元素。在其中,我们将放置一个幻灯片列表以及导航箭头。
每张幻灯片都将包含一个背景图像。当然,如果您愿意,请随时添加其他内容。
默认情况下,将显示第一张幻灯片。但是,我们可以通过将is-active 类附加到所需的幻灯片来配置该行为。
这是所需的标记:
<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. 定义样式
准备好标记后,我们将继续使用幻灯片的主要样式。
堆叠幻灯片
默认情况下,所有幻灯片都将堆叠在另一个之上。除了活动幻灯片之外,它们都将被隐藏。
以下是相关的样式:
.slideshow .slides {
display: grid;
}
.slideshow .slide {
grid-column: 1;
grid-row: 1;
opacity: 0;
transition: opacity 0.4s;
}
.slideshow .slide.is-active {
opacity: 1;
}
幻灯片中的每个人都div将接受cover课程。这会将其背景图像转换为全屏背景图像:
.cover {
background-size: cover;
background-repeat: no-repeat;
background-position: center;
height: 100vh;
}
导航
导航按钮将绝对位于幻灯片内部。每个按钮应覆盖幻灯片宽度的一半,并且它们的高度应等于幻灯片高度。
最初,所有按钮都将被隐藏。但是,当我们开始在幻灯片中移动光标时,相应的按钮将根据鼠标位置出现。
每个span按钮内部都有一个箭头(左或右)作为背景图像。
默认情况下,这些箭头的颜色为黑色。但是,当我们在幻灯片中移动光标时,它们的颜色应该会发生变化并与幻灯片图像形成对比。创建这种效果的技巧是 在s 中添加mix-blend-mode: difference (或exclusion) 和。filter: invert(1)span
继续前进,导航的样式如下:
.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. 添加javaScript
现在让我们为幻灯片添加交互性!
对于此示例,幻灯片将带有三个默认选项,我们可以通过指定关联的自定义属性来自定义它们:
选项 | 默认值 | 描述 |
---|---|---|
autoplay | 错误的 | 使幻灯片自动播放。 |
autoplay-interval | 4000 | 切换幻灯片之间的间隔时间,以毫秒为单位。 |
stop-autoplay-on-hover | 错误的 | 悬停时停止自动播放模式。 |
变量
在深入研究这些选项之前,作为第一步,我们将定义一组稍后将使用的变量:
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;
初始化事物
当所有页面资源都准备好后,我们将调用该init函数。
window.addeventListener("load", init);
此函数将触发四个子函数:
function init() {
changeSlide();
autoPlay();
stopAutoPlayOnHover();
customizeArrows();
}
正如我们稍后将看到的,这些函数中的每一个都将完成特定的任务。
循环播放幻灯片
该changeSlide函数将负责循环播放幻灯片。
每次单击按钮时,我们将执行以下操作:
获取当前活动幻灯片的副本。
is-active从活动幻灯片中删除课程。
检查以查看单击了哪个按钮。如果这是下一个按钮,我们会将is-active类添加到紧跟活动幻灯片的幻灯片中。如果没有这样的幻灯片,则第一张幻灯片将接收此类。
另一方面,如果单击上一个按钮,我们会将 is-active 类添加到活动幻灯片的上一张幻灯片。如果没有这样的幻灯片,则最后一张幻灯片将接收此类。
这是这个函数的签名:
// 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);
}
});
}
}
自动播放
该autoplay 函数将负责激活自动播放模式。
默认情况下,我们必须手动循环浏览幻灯片。
要激活自动播放,我们将data-autoplay="true"属性添加到幻灯片。
data-autoplay-interval="number" 我们还可以通过将(默认为 4000 毫秒)定义为第二个属性来调整切换幻灯片之间的间隔时间,如下所示:
<div class="slideshow" data-autoplay="true" data-autoplay-interval="6000">
...
</div>
这是这个函数的签名:
// variables here
function autoPlay() {
if (slideshow.dataset.autoplay === "true") {
intervalID = setInterval(() => {
nextBtn.click();
}, autoplayInterval);
}
}
停止自动播放
该stopAutoplayOnHover 函数将负责在悬停幻灯片时禁用自动播放模式。
要启用此功能,我们将data-stop-autoplay-on-hover="true"属性传递给幻灯片,如下所示:
<div class="slideshow" data-stop-autoplay-on-hover="true">
...
</div>
这是这个函数的签名:
// 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);
});
}
}
自定义箭头
该 customizeArrows 函数将负责操作导航按钮的可见性和它们的位置span。
正如我们之前讨论过的,导航按钮最初是隐藏的。
当我们在幻灯片中移动鼠标时,一次只会出现一个,具体取决于鼠标位置。其span元素的位置也将取决于鼠标指针的坐标。
一旦我们离开幻灯片,按钮将再次隐藏。
为了在各种屏幕/设备中实现这些要求,我们将使用两个鼠标事件和两个触摸事件。
这是实现此功能的代码:
// 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);
}
结论
就是这样,伙计们!在本教程中,我们设法通过编写纯 JavaScript 代码来实现灵活的全屏幻灯片。希望您喜欢这次旅程并获得了一些新知识!
以下是我们构建的内容的提醒:
See the Pen How to Build a Simple Full-Screen Slideshow With Vanilla JavaScript by Envato Tuts+ (@tutsplus) on CodePen.
- 堆叠幻灯片
- 导航
- 变量
- 初始化事物
- 循环播放幻灯片
- 自动播放
- 停止自动播放
- 自定义箭头