使

使用 JavaScript 的图像滑块

2025-05-25

使用 JavaScript 的图像滑块

在本文中,我们将创建一个简洁的图片滑块(也称为轮播)。它能够以精彩的动画效果滑动图片,并跟踪当前图片,您可以通过底部的圆点看到当前图片。首先,让我们看看我们要构建什么。

预览

预览

HTML



<div class="container-slider">

  <!-- Slider Container with images...  -->
  <div class="slides"></div>

  <!--  Previous Button  -->
  <button class="btn-slide prev">
    <img src="https://imgur.com/SUyRJqI.png" alt="prevBtn" />
  </button>

  <!--  Next Button  -->
  <button class="btn-slide next">
    <img src=" https://imgur.com/M6rDsRR.png" alt="nextBtn" />
  </button>

  <!--  Container for dots  -->
  <div class="container-dots"></div>
</div>


Enter fullscreen mode Exit fullscreen mode

div我们将创建一个带有 类的outer .container-slider。它将有四个独立的子类。

  • .slides:它将包含图像,但我们还没有在 HTML 中添加它们,我们将使用 JS 添加它们。
  • .btn-slide:在父容器(.container-slider)中将有两个按钮,一个用于下一张图片(.next),另一个用于上一张图片(.prev
  • .container-dots.dot:这是我们尚未添加的容器。它也将像图片一样由 JS 完成。

想必你现在已经大致了解了我们正在做的事情。现在我们开始讨论 CSS。

CSS



* {
  margin: 0;
  padding: 0;
}

body {
  background: azure;
  min-height: 100vh;
  padding: 0 25px;
}

/* Main Wrapper Container */
.container-slider {
  position: relative;
  max-width: 700px;
  width: 100%;
  height: 400px;
  border-radius: 20px;
  box-shadow: 0 0 20px rgba(0, 0, 0, 0.5);
  overflow: hidden;
}

/* Slider Container which contains images */
.slides {
  position: relative;
  width: 100%;
  height: 100%;
}

/* Default Image Properties */
.slides img {
  position: absolute;
  width: 50px;
  height: 50px;
  object-fit: cover;
  object-position: center;
  opacity: 0;
  transform: scale(0);
  transition: all 0.5s ease-in-out;
  transition-delay: 500ms;
}

/* Active Image or Current image to display */
.slides > img[data-active] {
  opacity: 1;
  transform: scale(1);
  transition-delay: 0ms;
  width: 100%;
  height: 100%;
  z-index: 10;
}

/* Image Slider Next And Previous Buttons */
.btn-slide {
  position: absolute;
  background: #f1f1f1;
  width: 40px;
  height: 40px;
  padding: 10px;
  border-radius: 50%;
  opacity: 0;
  border: 1px solid rgba(34, 34, 34, 0.287);
  transition: opacity 300ms ease-in-out;
  cursor: pointer;
  overflow: hidden;
  z-index: 10;
}

.btn-slide > img {
  width: 100%;
}

/* Show Buttons when user hover on the slider Container */
.container-slider:hover > .btn-slide {
  opacity: 1;
}

/* Previous and Next Button Position Absolute */
.prev,
.next {
  top: 50%;
  transform: translateY(-60%);
}

.prev {
  left: 20px;
}
.next {
  right: 20px;
}

/* Bottom Dots Container  */
.container-dots {
  position: absolute;
  bottom: 20px;
  width: 100%;
  display: flex;
  justify-content: center;
  z-index: 10;
}

/* Sigle Dot style */
.dot {
  width: 10px;
  height: 10px;
  border-radius: 50%;
  border: 3px solid #f1f1f1;
  margin: 0 5px;
  background: #f1f1f1;
  cursor: pointer;
  transition: background-color 500ms ease-in-out;
}

/* Change the color of bg when user hover on it. */
.dot:hover {
  opacity: 0.9;
  background: rgb(32, 32, 32);
}

/* Current or active dot */
.dot[data-active="true"] {
  background: rgb(32, 32, 32);
}


Enter fullscreen mode Exit fullscreen mode

CSS 中的所有内容都是不言自明的,所以我就不多说了。如果你对 CSS 有任何疑问,请在下面留言。

JavaScript

好戏就此开始。让我们从头开始看看。首先,我们需要导入两个容器,分别是. Slides. Container-dots



const slides = document.querySelector(".slides");
const containerDots = document.querySelector(".container-dots");


Enter fullscreen mode Exit fullscreen mode

现在我们需要将图片添加到.slides容器中。我们还需要一个全局计数器或全局索引来跟踪当前正在显示的图片。



// Global Index to track Image
var slideIndex = 1;

// Images container
const images = [
  { src: "https://rb.gy/ohx0bd" },
  { src: "https://rb.gy/gggxy8" },
  { src: "https://rb.gy/z2a0fy" },
  { src: "https://rb.gy/nsefjh" },
  { src: "https://rb.gy/dssu2a" }
];


Enter fullscreen mode Exit fullscreen mode

现在我们有了图像,现在让我们把它们添加到 中,.slides并且我们还需要将它们添加.dot到 中.container-dots。图像总数和点总数应该相同,例如,有五幅图像,那么就应该有五个点。让我们看看该怎么做。



// Adding images and dots to the Respective Container
images.map((img) => {
  // Creating Image Element and adding src of that image
  var imgTag = document.createElement("img");
  imgTag.src = img.src;

  // Creating Dot (div) Element adding 'dot' class to it
  var dot = document.createElement("div");
  dot.classList.add("dot");

  //  Appending the image and dots to respective container
  slides.appendChild(imgTag);
  containerDots.appendChild(dot);
});


Enter fullscreen mode Exit fullscreen mode

它会完成这个任务,并将它们添加到各自的容器中。现在我们需要按钮添加到滑块中。我们也来做一下。我们需要两个按钮.prev.next我们已经将它们添加到 HTML 中,现在只需让它们工作即可。

下一张幻灯片按钮



// Slide Next Button Click Event
const nextSlide = () => {
    // it will update the slideIndex on the basis of the images.length as it gets greater than images.length, this will initialize to the 1
  if (slideIndex !== images.length) {
    ++slideIndex;
  } else if (slideIndex === images.length) {
    slideIndex = 1;
  }
};

const nextBtn = document.querySelector(".next");
nextBtn.onclick = nextSlide;


Enter fullscreen mode Exit fullscreen mode

上一张幻灯片按钮



// Slide Previous Button Click Event
const prevSlide = () => {
    // It will check if the slideIndex is less equal to 1 then change it to the images.legnth, it will enable infinite scrolling
  if (slideIndex !== 1) {
    --slideIndex;
  } else if (slideIndex === 1) {
    slideIndex = images.length;
  }
};

const prevBtn = document.querySelector(".prev");
prevBtn.onclick = prevSlide;


Enter fullscreen mode Exit fullscreen mode

现在这些按钮将允许您根据slideIndex

但是在实现它之后,你会看到图像没有显示,这是因为我们没有根据现在的情况更新图像slideIndex,让我们来实现它。



// Update Image And Slide Dot according to the [data-active]
function updateImageAndDot() {
  /* ...........Updating Image.............. */
  const activeSlide = slides.querySelector("[data-active]");
  slides.children[slideIndex - 1].dataset.active = true;
  activeSlide && delete activeSlide.dataset.active;

  /* ...........Updating Dots.............. */
  const activeDot = containerDots.querySelector("[data-active]");
  containerDots.children[slideIndex - 1].dataset.active = true;
  activeDot && delete activeDot.dataset.active;
}


Enter fullscreen mode Exit fullscreen mode

这里我们获取了activeSlideactiveDot。它们会有一个属性,然后我们根据 ,将和 的子元素[data-active]设置为活动状态 (data-active="true)" 。如果之前查询过 ,则删除它(也就是之前活动的幻灯片和点)。这样,当前就只有一个处于活动状态的幻灯片和点了。.slides.container-dotsslideIndexactiveSlide

现在我们需要在nextSlideandprevSlide函数中调用这个函数。



const nextSlide = () => {
  /* .... */
  updateImageAndDot();
};

const prevSlide = () => {
  /* .... */
  updateImageAndDot();
};


Enter fullscreen mode Exit fullscreen mode

我们还需要在全局范围内调用updateImageAndDot。这将允许它在页面加载时显示图像和点。



// Show the Image as the page loads;
updateImageAndDot();


Enter fullscreen mode Exit fullscreen mode

现在我们将实现另一个功能,即当用户按下点时,它会将用户带到相应的图像。

预览-2

其实并不难,我们只需要创建一个函数,moveDot并为每个点添加事件监听器即可。让我们看看它的实际效果。



// It helps to move the dot, it take "index" as parameter and update the slideIndex
function moveDot(index) {
  slideIndex = index;
  updateImageAndDot();  // to update the image and dot
}

// Adding EventListener to All dots so that when user click on it trigger move dots;
const dots = containerDots.querySelectorAll("*").forEach((dot, index) => {
  dot.addEventListener("click", () => {
    moveDot(index + 1);
  });
});


Enter fullscreen mode Exit fullscreen mode

现在我们已经涵盖了所有方面,现在让我们看看完整的 Javascript 文件或代码。



const slides = document.querySelector(".slides");
const containerDots = document.querySelector(".container-dots");

var slideIndex = 1;

// Images container
const images = [
  { src: "https://rb.gy/ohx0bd" },
  { src: "https://rb.gy/gggxy8" },
  { src: "https://rb.gy/z2a0fy" },
  { src: "https://rb.gy/nsefjh" },
  { src: "https://rb.gy/dssu2a" }
];

// Adding images and dots to the Respective Container
images.map((img) => {
  // Creating Image Element and adding src of that image
  var imgTag = document.createElement("img");
  imgTag.src = img.src;

  // Creating Dot (div) Element adding 'dot' class to it
  var dot = document.createElement("div");
  dot.classList.add("dot");

  //  Appending the image and dots to respective container
  slides.appendChild(imgTag);
  containerDots.appendChild(dot);
});

// Adding EventListener to All dots so that when user click on it trigger move dots;
const dots = containerDots.querySelectorAll("*").forEach((dot, index) => {
  dot.addEventListener("click", () => {
    moveDot(index + 1);
  });
});

// It helps to move the dot, it take "index" as parameter and update the slideIndex
function moveDot(index) {
  slideIndex = index;
  updateImageAndDot();
}

// Update Image And Slide Dot according to the [data-active]
function updateImageAndDot() {
  /* ...........Updating Image.............. */
  const activeSlide = slides.querySelector("[data-active]");
  slides.children[slideIndex - 1].dataset.active = true;
  activeSlide && delete activeSlide.dataset.active;

  /* ...........Updating Dots.............. */
  const activeDot = containerDots.querySelector("[data-active]");
  containerDots.children[slideIndex - 1].dataset.active = true;
  activeDot && delete activeDot.dataset.active;
}

// Slide Next Button Click Event
const nextSlide = () => {
  // it will update the slideIndex on the basis of the images.length as it gets greater than images.length, this will initialize to the 1
  if (slideIndex !== images.length) {
    ++slideIndex;
  } else if (slideIndex === images.length) {
    slideIndex = 1;
  }
  updateImageAndDot();
};

const nextBtn = document.querySelector(".next");
nextBtn.onclick = nextSlide;

// Slide Previous Button Click Event
const prevSlide = () => {
  // It will check if the slideIndex is less equal to 1 then change it to the images.legnth, it will enable infinite scrolling
  if (slideIndex !== 1) {
    --slideIndex;
  } else if (slideIndex === 1) {
    slideIndex = images.length;
  }
  updateImageAndDot();
};

const prevBtn = document.querySelector(".prev");
prevBtn.onclick = prevSlide;

// Show the Image as the Page Loads;
updateImageAndDot();



Enter fullscreen mode Exit fullscreen mode

代码笔

总结

希望你喜欢这篇文章,如果喜欢,别忘了点赞❤️。你也可以收藏它,方便以后使用。制作这个滑块的过程很有趣,如果你有任何疑问或建议,欢迎随时提出。再见!

你可以给我买一杯咖啡来表示你的支持。😊👇
buymecoffee

您可能感兴趣 -

文章来源:https://dev.to/j471n/image-slider-with-vanila-js-22bf
PREV
值得收藏的 JavaScript 速查表
NEXT
我使用 HTML 和 CSS 制作了所有国家的国旗