代码之家  ›  专栏  ›  技术社区  ›  John Sall

只有第一个转盘在同一页面中的多个转盘中工作

  •  0
  • John Sall  · 技术社区  · 2 年前

    我试图添加for循环来遍历每个旋转木马,但当我这样做时,现在它们都不起作用。在我添加for循环之前,只有第一个循环有效。

    最初是:

    querySelector('.carousel')
    

    然后我把它改成:

    querySelectorAll('.carousel')
    

    var carousel = document.querySelectorAll('.carousel'), i;
    
    for (i = 0; i < carousel.length; ++i) {
    
    firstImg = carousel[i].querySelectorAll("img")[0];
    arrowIcons = document.querySelectorAll(".wrapper i");
    
    let isDragStart = false, isDragging = false, prevPageX, prevScrollLeft, positionDiff;
    
    
    
    
    carousel[i].addEventListener("mousedown", dragStart);
    carousel[i].addEventListener("touchstart", dragStart);
    
    document.addEventListener("mousemove", dragging);
    carousel[i].addEventListener("touchmove", dragging);
    
    document.addEventListener("mouseup", dragStop);
    carousel[i].addEventListener("touchend", dragStop);
    }
    
    
    const showHideIcons = () => {
        // showing and hiding prev/next icon according to carousel scroll left value
        let scrollWidth = carousel.scrollWidth - carousel.clientWidth; // getting max scrollable width
        arrowIcons[0].style.display = carousel.scrollLeft == 0 ? "none" : "block";
        arrowIcons[1].style.display = carousel.scrollLeft == scrollWidth ? "none" : "block";
    }
    
    arrowIcons.forEach(icon => {
        icon.addEventListener("click", () => {
            let firstImgWidth = firstImg.clientWidth + 14; // getting first img width & adding 14 margin value
            // if clicked icon is left, reduce width value from the carousel scroll left else add to it
            carousel.scrollLeft += icon.id == "left" ? -firstImgWidth : firstImgWidth;
            setTimeout(() => showHideIcons(), 60); // calling showHideIcons after 60ms
        });
    });
    
    const autoSlide = () => {
        // if there is no image left to scroll then return from here
        if(carousel.scrollLeft - (carousel.scrollWidth - carousel.clientWidth) > -1 || carousel.scrollLeft <= 0) return;
    
        positionDiff = Math.abs(positionDiff); // making positionDiff value to positive
        let firstImgWidth = firstImg.clientWidth + 14;
        // getting difference value that needs to add or reduce from carousel left to take middle img center
        let valDifference = firstImgWidth - positionDiff;
    
        if(carousel.scrollLeft > prevScrollLeft) { // if user is scrolling to the right
            return carousel.scrollLeft += positionDiff > firstImgWidth / 3 ? valDifference : -positionDiff;
        }
        // if user is scrolling to the left
        carousel.scrollLeft -= positionDiff > firstImgWidth / 3 ? valDifference : -positionDiff;
    }
    
    const dragStart = (e) => {
        // updatating global variables value on mouse down event
        isDragStart = true;
        prevPageX = e.pageX || e.touches[0].pageX;
        prevScrollLeft = carousel.scrollLeft;
    }
    
    const dragging = (e) => {
        // scrolling images/carousel to left according to mouse pointer
        if(!isDragStart) return;
        e.preventDefault();
        isDragging = true;
        carousel.classList.add("dragging");
        positionDiff = (e.pageX || e.touches[0].pageX) - prevPageX;
        carousel.scrollLeft = prevScrollLeft - positionDiff;
        showHideIcons();
    }
    
    const dragStop = () => {
        isDragStart = false;
        carousel.classList.remove("dragging");
    
        if(!isDragging) return;
        isDragging = false;
        autoSlide();
    }
    /* Import Google font - Poppins */
    @import url('https://fonts.googleapis.com/css2?family=Poppins:wght@400;500;600&display=swap');
    *{
      margin: 0;
      padding: 0;
      box-sizing: border-box;
      font-family: 'Poppins', sans-serif;
    }
    body{
      //display: flex;
      padding: 0 35px;
      min-height: 100vh;
      align-items: center;
      justify-content: center;
      background: #343F4F;
    }
    .wrapper{
      display: flex;
      max-width: 1200px;
      position: relative;
    }
    .wrapper i{
      top: 50%;
      height: 44px;
      width: 44px;
      color: #343F4F;
      cursor: pointer;
      font-size: 1.15rem;
      position: absolute;
      text-align: center;
      line-height: 44px;
      background: #fff;
      border-radius: 50%;
      transform: translateY(-50%);
      transition: transform 0.1s linear;
    }
    .wrapper i:active{
      transform: translateY(-50%) scale(0.9);
    }
    .wrapper i:hover{
      background: #f2f2f2;
    }
    .wrapper i:first-child{
      left: -22px;
      display: none;
    }
    .wrapper i:last-child{
      right: -22px;
    }
    .wrapper .carousel{
      font-size: 0px;
      cursor: pointer;
      overflow: hidden;
      white-space: nowrap;
      scroll-behavior: smooth;
    }
    .carousel.dragging{
      cursor: grab;
      scroll-behavior: auto;
    }
    .carousel.dragging img{
      pointer-events: none;
    }
    .carousel img{
      height: 340px;
      object-fit: cover;
      user-select: none;
      margin-left: 14px;
      width: calc(100% / 3);
    }
    .carousel img:first-child{
      margin-left: 0px;
    }
    
    @media screen and (max-width: 900px) {
      .carousel img{
        width: calc(100% / 2);
      }
    }
    
    @media screen and (max-width: 550px) {
      .carousel img{
        width: 100%;
      }
    }
    <!DOCTYPE html>
    <html lang="en" dir="ltr">
      <head>
        <meta charset="utf-8">
        <title>Draggable Image Slider | CodingNepal</title>
        <link rel="stylesheet" href="style.css">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.2.0/css/all.min.css">
      </head>
      <body>
      <div>
      
        <div class="wrapper">
          <i id="left" class="fa-solid fa-angle-left"></i>
          <div class="carousel">
            <img src="https://codeskulptor-demos.commondatastorage.googleapis.com/GalaxyInvaders/back04.jpg" alt="img" draggable="false">
            <img src="https://codeskulptor-demos.commondatastorage.googleapis.com/GalaxyInvaders/back02.jpg" alt="img" draggable="false">
            <img src="https://codeskulptor-demos.commondatastorage.googleapis.com/GalaxyInvaders/back01.jpg" alt="img" draggable="false">
            <img src="https://codeskulptor-demos.commondatastorage.googleapis.com/GalaxyInvaders/back05.jpg" alt="img" draggable="false">
            <img src="https://codeskulptor-demos.commondatastorage.googleapis.com/GalaxyInvaders/back07.jpg" alt="img" draggable="false">
            
            
          </div>
          <i id="right" class="fa-solid fa-angle-right"></i>
        </div>
        
        </div>
        
        <p>
        hihifdd
        </p>
        <div class="wrapper">
          <i id="left" class="fa-solid fa-angle-left"></i>
          <div class="carousel">
            <img src="https://codeskulptor-demos.commondatastorage.googleapis.com/GalaxyInvaders/back04.jpg" alt="img" draggable="false">
            <img src="https://codeskulptor-demos.commondatastorage.googleapis.com/GalaxyInvaders/back02.jpg" alt="img" draggable="false">
            <img src="https://codeskulptor-demos.commondatastorage.googleapis.com/GalaxyInvaders/back01.jpg" alt="img" draggable="false">
            <img src="https://codeskulptor-demos.commondatastorage.googleapis.com/GalaxyInvaders/back05.jpg" alt="img" draggable="false">
            <img src="https://codeskulptor-demos.commondatastorage.googleapis.com/GalaxyInvaders/back07.jpg" alt="img" draggable="false">
            
          </div>
          <i id="right" class="fa-solid fa-angle-right"></i>
        </div>
        
      </body>
    </html>
    1 回复  |  直到 2 年前
        1
  •  1
  •   Wongjn    2 年前

    您可能希望将其余的函数引入 for 循环,并调整代码,使函数引用正在迭代的curent carousel元素的属性:

    var carousel = document.querySelectorAll(".carousel"),
      i;
    
    for (i = 0; i < carousel.length; ++i) {
      const thisCourusel = carousel[i];
      const firstImg = thisCourusel.querySelectorAll("img")[0];
      const arrowIcons = thisCourusel.closest(".wrapper").querySelectorAll("i");
    
      let isDragStart = false,
        isDragging = false,
        prevPageX,
        prevScrollLeft,
        positionDiff;
    
      const dragStart = (e) => {
        // updatating global variables value on mouse down event
        isDragStart = true;
        prevPageX = e.pageX || e.touches[0].pageX;
        prevScrollLeft = thisCourusel.scrollLeft;
      };
    
      const dragging = (e) => {
        // scrolling images/carousel to left according to mouse pointer
        if (!isDragStart) return;
        e.preventDefault();
        isDragging = true;
        thisCourusel.classList.add("dragging");
        positionDiff = (e.pageX || e.touches[0].pageX) - prevPageX;
        thisCourusel.scrollLeft = prevScrollLeft - positionDiff;
        showHideIcons();
      };
    
      const dragStop = () => {
        isDragStart = false;
        thisCourusel.classList.remove("dragging");
    
        if (!isDragging) return;
        isDragging = false;
        autoSlide();
      };
    
      thisCourusel.addEventListener("mousedown", dragStart);
      thisCourusel.addEventListener("touchstart", dragStart);
    
      document.addEventListener("mousemove", dragging);
      thisCourusel.addEventListener("touchmove", dragging);
    
      document.addEventListener("mouseup", dragStop);
      thisCourusel.addEventListener("touchend", dragStop);
    
      const showHideIcons = () => {
        // showing and hiding prev/next icon according to carousel scroll left value
        let scrollWidth = thisCourusel.scrollWidth - thisCourusel.clientWidth; // getting max scrollable width
        arrowIcons[0].style.display =
          thisCourusel.scrollLeft == 0 ? "none" : "block";
        arrowIcons[1].style.display =
          thisCourusel.scrollLeft == scrollWidth ? "none" : "block";
      };
    
      arrowIcons.forEach((icon) => {
        icon.addEventListener("click", () => {
          let firstImgWidth = firstImg.clientWidth + 14; // getting first img width & adding 14 margin value
          // if clicked icon is left, reduce width value from the carousel scroll left else add to it
          thisCourusel.scrollLeft +=
            icon.id == "left" ? -firstImgWidth : firstImgWidth;
          setTimeout(() => showHideIcons(), 60); // calling showHideIcons after 60ms
        });
      });
    
      const autoSlide = () => {
        // if there is no image left to scroll then return from here
        if (
          thisCourusel.scrollLeft -
            (thisCourusel.scrollWidth - thisCourusel.clientWidth) >
            -1 ||
          thisCourusel.scrollLeft <= 0
        )
          return;
    
        positionDiff = Math.abs(positionDiff); // making positionDiff value to positive
        let firstImgWidth = firstImg.clientWidth + 14;
        // getting difference value that needs to add or reduce from carousel left to take middle img center
        let valDifference = firstImgWidth - positionDiff;
    
        if (carousel.scrollLeft > prevScrollLeft) {
          // if user is scrolling to the right
          return (thisCourusel.scrollLeft +=
            positionDiff > firstImgWidth / 3 ? valDifference : -positionDiff);
        }
        // if user is scrolling to the left
        thisCourusel.scrollLeft -=
          positionDiff > firstImgWidth / 3 ? valDifference : -positionDiff;
      };
    }
    /* Import Google font - Poppins */
    @import url("https://fonts.googleapis.com/css2?family=Poppins:wght@400;500;600&display=swap");
    * {
      margin: 0;
      padding: 0;
      box-sizing: border-box;
      font-family: "Poppins", sans-serif;
    }
    body {
      //display: flex;
      padding: 0 35px;
      min-height: 100vh;
      align-items: center;
      justify-content: center;
      background: #343f4f;
    }
    .wrapper {
      display: flex;
      max-width: 1200px;
      position: relative;
    }
    .wrapper i {
      top: 50%;
      height: 44px;
      width: 44px;
      color: #343f4f;
      cursor: pointer;
      font-size: 1.15rem;
      position: absolute;
      text-align: center;
      line-height: 44px;
      background: #fff;
      border-radius: 50%;
      transform: translateY(-50%);
      transition: transform 0.1s linear;
    }
    .wrapper i:active {
      transform: translateY(-50%) scale(0.9);
    }
    .wrapper i:hover {
      background: #f2f2f2;
    }
    .wrapper i:first-child {
      left: -22px;
      display: none;
    }
    .wrapper i:last-child {
      right: -22px;
    }
    .wrapper .carousel {
      font-size: 0px;
      cursor: pointer;
      overflow: hidden;
      white-space: nowrap;
      scroll-behavior: smooth;
    }
    .carousel.dragging {
      cursor: grab;
      scroll-behavior: auto;
    }
    .carousel.dragging img {
      pointer-events: none;
    }
    .carousel img {
      height: 340px;
      object-fit: cover;
      user-select: none;
      margin-left: 14px;
      width: calc(100% / 3);
    }
    .carousel img:first-child {
      margin-left: 0px;
    }
    
    @media screen and (max-width: 900px) {
      .carousel img {
        width: calc(100% / 2);
      }
    }
    
    @media screen and (max-width: 550px) {
      .carousel img {
        width: 100%;
      }
    }
    <!doctype html>
    <html lang="en" dir="ltr">
      <head>
        <meta charset="utf-8" />
        <title>Draggable Image Slider | CodingNepal</title>
        <link rel="stylesheet" href="style.css" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <link
          rel="stylesheet"
          href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.2.0/css/all.min.css"
        />
      </head>
      <body>
        <div>
          <div class="wrapper">
            <i id="left" class="fa-solid fa-angle-left"></i>
            <div class="carousel">
              <img
                src="https://codeskulptor-demos.commondatastorage.googleapis.com/GalaxyInvaders/back04.jpg"
                alt="img"
                draggable="false"
              />
              <img
                src="https://codeskulptor-demos.commondatastorage.googleapis.com/GalaxyInvaders/back02.jpg"
                alt="img"
                draggable="false"
              />
              <img
                src="https://codeskulptor-demos.commondatastorage.googleapis.com/GalaxyInvaders/back01.jpg"
                alt="img"
                draggable="false"
              />
              <img
                src="https://codeskulptor-demos.commondatastorage.googleapis.com/GalaxyInvaders/back05.jpg"
                alt="img"
                draggable="false"
              />
              <img
                src="https://codeskulptor-demos.commondatastorage.googleapis.com/GalaxyInvaders/back07.jpg"
                alt="img"
                draggable="false"
              />
            </div>
            <i id="right" class="fa-solid fa-angle-right"></i>
          </div>
        </div>
    
        <p>hihifdd</p>
        <div class="wrapper">
          <i id="left" class="fa-solid fa-angle-left"></i>
          <div class="carousel">
            <img
              src="https://codeskulptor-demos.commondatastorage.googleapis.com/GalaxyInvaders/back04.jpg"
              alt="img"
              draggable="false"
            />
            <img
              src="https://codeskulptor-demos.commondatastorage.googleapis.com/GalaxyInvaders/back02.jpg"
              alt="img"
              draggable="false"
            />
            <img
              src="https://codeskulptor-demos.commondatastorage.googleapis.com/GalaxyInvaders/back01.jpg"
              alt="img"
              draggable="false"
            />
            <img
              src="https://codeskulptor-demos.commondatastorage.googleapis.com/GalaxyInvaders/back05.jpg"
              alt="img"
              draggable="false"
            />
            <img
              src="https://codeskulptor-demos.commondatastorage.googleapis.com/GalaxyInvaders/back07.jpg"
              alt="img"
              draggable="false"
            />
          </div>
          <i id="right" class="fa-solid fa-angle-right"></i>
        </div>
      </body>
    </html>

    您可能应该使用 forEach() 循环以使代码更加清晰,例如:

    document.querySelectorAll(".carousel").forEach((carousel) => {
      const firstImg = carousel.querySelectorAll("img")[0];
      const arrowIcons = carousel.closest(".wrapper").querySelectorAll("i");
    
      let isDragStart = false,
        isDragging = false,
        prevPageX,
        prevScrollLeft,
        positionDiff;
    
      const dragStart = (e) => {
        // updatating global variables value on mouse down event
        isDragStart = true;
        prevPageX = e.pageX || e.touches[0].pageX;
        prevScrollLeft = carousel.scrollLeft;
      };
    
      const dragging = (e) => {
        // scrolling images/carousel to left according to mouse pointer
        if (!isDragStart) return;
        e.preventDefault();
        isDragging = true;
        carousel.classList.add("dragging");
        positionDiff = (e.pageX || e.touches[0].pageX) - prevPageX;
        carousel.scrollLeft = prevScrollLeft - positionDiff;
        showHideIcons();
      };
    
      const dragStop = () => {
        isDragStart = false;
        carousel.classList.remove("dragging");
    
        if (!isDragging) return;
        isDragging = false;
        autoSlide();
      };
    
      carousel.addEventListener("mousedown", dragStart);
      carousel.addEventListener("touchstart", dragStart);
    
      document.addEventListener("mousemove", dragging);
      carousel.addEventListener("touchmove", dragging);
    
      document.addEventListener("mouseup", dragStop);
      carousel.addEventListener("touchend", dragStop);
    
      const showHideIcons = () => {
        // showing and hiding prev/next icon according to carousel scroll left value
        let scrollWidth = carousel.scrollWidth - carousel.clientWidth; // getting max scrollable width
        arrowIcons[0].style.display = carousel.scrollLeft == 0 ? "none" : "block";
        arrowIcons[1].style.display =
          carousel.scrollLeft == scrollWidth ? "none" : "block";
      };
    
      arrowIcons.forEach((icon) => {
        icon.addEventListener("click", () => {
          let firstImgWidth = firstImg.clientWidth + 14; // getting first img width & adding 14 margin value
          // if clicked icon is left, reduce width value from the carousel scroll left else add to it
          carousel.scrollLeft += icon.id == "left" ? -firstImgWidth : firstImgWidth;
          setTimeout(() => showHideIcons(), 60); // calling showHideIcons after 60ms
        });
      });
    
      const autoSlide = () => {
        // if there is no image left to scroll then return from here
        if (
          carousel.scrollLeft - (carousel.scrollWidth - carousel.clientWidth) >
            -1 ||
          carousel.scrollLeft <= 0
        )
          return;
    
        positionDiff = Math.abs(positionDiff); // making positionDiff value to positive
        let firstImgWidth = firstImg.clientWidth + 14;
        // getting difference value that needs to add or reduce from carousel left to take middle img center
        let valDifference = firstImgWidth - positionDiff;
    
        if (carousel.scrollLeft > prevScrollLeft) {
          // if user is scrolling to the right
          return (carousel.scrollLeft +=
            positionDiff > firstImgWidth / 3 ? valDifference : -positionDiff);
        }
        // if user is scrolling to the left
        carousel.scrollLeft -=
          positionDiff > firstImgWidth / 3 ? valDifference : -positionDiff;
      };
    });
    /*导入谷歌字体-Poppins*/
    @导入url(“https://fonts.googleapis.com/css2?family=Poppins:wght@400;500;600&display=swap”);
    * {
    裕度:0;
    填充:0;
    框大小:边框框;
    font-family:“Poppins”,无衬线;
    }
    身体{
    //显示:flex;
    填充:0 35px;
    最小高度:100vh;
    对齐项目:居中;
    证明内容:中心;
    背景:#3343f4f;
    }
    .包装器{
    显示:flex;
    最大宽度:1200px;
    位置:相对;
    }
    .包装纸i{
    顶部:50%;
    高度:44px;
    宽度:44px;
    颜色:#3343f4f;
    游标:指针;
    字体大小:1.15rem;
    位置:绝对;
    文本对齐:居中;
    线条高度:44px;
    背景:#fff;
    边界半径:50%;
    transform:translateY(-50%);
    转换:转换0.1s线性;
    }
    .wapper i:活动{
    transform:translateY(-50%)比例(0.9);
    }
    .wapper i:悬停{
    背景:;
    }
    .包装纸i:第一个孩子{
    左:-22像素;
    显示:无;
    }
    .包装纸i:最后一个孩子{
    右:-22像素;
    }
    .包装器.转盘{
    字体大小:0px;
    游标:指针;
    溢出:隐藏;
    空白:nowrap;
    滚动行为:平滑;
    }
    .转盘.拖动{
    光标:抓取;
    滚动行为:自动;
    }
    .转盘.拖动img{
    指针事件:无;
    }
    .转盘img{
    高度:340px;
    对象适合:封面;
    用户选择:无;
    左边距:14px;
    宽度:calc(100%/3);
    }
    .coroundle img:第一个子项{
    左边距:0px;
    }
    
    @媒体屏幕和(最大宽度:900px){
    .转盘img{
    宽度:calc(100%/2);
    }
    }
    
    @媒体屏幕和(最大宽度:550px){
    .转盘img{
    宽度:100%;
    }
    }
    <!doctype html>
    <html lang=“en”dir=“ltr”>
    <头部>
    <meta字符集=“utf-8”/>
    <标题>可拖动的图像滑块|CodingNepal</标题>
    <link rel=“stylesheet”href=“style.css”/>
    <meta name=“viewport”content=“width=设备宽度,初始比例=1.0”/>
    <链接
    rel=“样式表”
    href=“https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.2.0/css/all.min.css"
    />
    </头部>
    <身体>
    <div>
    <div class=“wrapper”>
    <i id=“left”class=“fa实心fa角度left”></i>
    <div class=“转盘”>
    <img
    src=“https://codeskulptor-demos.commondatastorage.googleapis.com/GalaxyInvaders/back04.jpg"
    alt=“img”
    draggable=“false”
    />
    <img
    src=“https://codeskulptor-demos.commondatastorage.googleapis.com/GalaxyInvaders/back02.jpg"
    alt=“img”
    draggable=“false”
    />
    <img
    src=“https://codeskulptor-demos.commondatastorage.googleapis.com/GalaxyInvaders/back01.jpg"
    alt=“img”
    draggable=“false”
    />
    <img
    src=“https://codeskulptor-demos.commondatastorage.googleapis.com/GalaxyInvaders/back05.jpg"
    alt=“img”
    draggable=“false”
    />
    <img
    src=“https://codeskulptor-demos.commondatastorage.googleapis.com/GalaxyInvaders/back07.jpg"
    alt=“img”
    draggable=“false”
    />
    </div>
    <i id=“right”class=“fa solid fa angle right”></i>
    </div>
    </div>
    
    <p>hihifdd</p>
    <div class=“wrapper”>
    <i id=“left”class=“fa实心fa角度left”></i>
    <div class=“转盘”>
    <img
    src=“https://codeskulptor-demos.commondatastorage.googleapis.com/GalaxyInvaders/back04.jpg"
    alt=“img”
    draggable=“false”
    />
    <img
    src=“https://codeskulptor-demos.commondatastorage.googleapis.com/GalaxyInvaders/back02.jpg"
    alt=“img”
    draggable=“false”
    />
    <img
    src=“https://codeskulptor-demos.commondatastorage.googleapis.com/GalaxyInvaders/back01.jpg"
    alt=“img”
    draggable=“false”
    />
    <img
    src=“https://codeskulptor-demos.commondatastorage.googleapis.com/GalaxyInvaders/back05.jpg"
    alt=“img”
    draggable=“false”
    />
    <img
    src=“https://codeskulptor-demos.commondatastorage.googleapis.com/GalaxyInvaders/back07.jpg"
    alt=“img”
    draggable=“false”
    />
    </div>
    <i id=“right”class=“fa solid fa angle right”></i>
    </div>
    </身体>
    </html>

    这里的好处是,您不会得到的命名之间的不和谐 carousel 变量,我希望它对于集合转盘是复数。