vanilla_如何使用Vanilla JavaScript构建简单的全屏幻灯片

本文介绍如何仅使用纯JavaScript创建响应式全屏幻灯片。涵盖幻灯片的CSS样式、自动播放功能及鼠标悬停时的交互效果。

vanilla

在本教程中,您将学习如何使用纯JavaScript创建响应式全屏幻灯片。 要构建它,我们将经历几个不同的前端技巧。 另外,当我们将鼠标悬停在幻灯片上时,我们将更进一步,自定义光标的外观。

与往常一样,要初步了解我们将要构建的内容,请查看相关的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都会有一个箭头(向左或向右)作为背景图像。

默认情况下,这些箭头的颜色将为黑色。 但是,当我们在幻灯片放映中移动光标时,它们的颜色应该改变并与幻灯片图像形成对比。 创建此效果的技巧是在span s中添加mix-blend-mode: difference (或exclusion )和filter: invert(1)

继续,导航样式如下:

.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函数将负责遍历幻灯片。

每次单击按钮时,我们将执行以下操作:

  1. 获取当前活动幻灯片的副本。
  2. 从活动幻灯片中删除is-active类。
  3. 检查以查看单击了哪个按钮。 如果这是下一个按钮,则将is-active类添加到幻灯片中,该类紧随活动幻灯片之后。 如果没有这样的幻灯片,则第一张幻灯片将获得此类课程。
  4. 另一方面,如果单击上一个按钮,我们会将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" (默认值为4000ms)定义为第二个属性来调整切换幻灯片之间的间隔时间,如下所示:

<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悬停在幻灯片上时, 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代码设法实现了灵活的全屏幻灯片显示。 希望您喜欢这个旅程并获得了一些新知识!

这提醒我们建立了什么:

您可以做很多事情来增强此幻灯片的功能。 这里有一些想法:

与往常一样,非常感谢您的阅读!

翻译自: https://webdesign.tutsplus.com/tutorials/simple-full-screen-slideshow-with-vanilla-javascript--cms-34624

vanilla

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值