使用滚动对齐对齐到达第一个/最后一个元素时,下一个/上一个按钮不会隐藏

问题描述 投票:0回答:1

我正在尝试制作显示 3 个项目的轮播,其宽度缩放为其父项的 100%/3。

下一个上一个按钮可以正常工作,并且只要它们到达元素 [0] 和 [1] 的边缘,显示隐藏功能就可以正常工作。

如果我从 [0] 开始,上一个按钮仍然隐藏,当我按下下一个按钮时,该项目将完美滚动并显示上一个按钮,但是当我到达最后一个项目时,下一个按钮不会立即隐藏除非我再按一次,否则它将被隐藏,与上一个按钮相同,如果我返回到第一个元素,它不会立即隐藏,除非我再按一次。

this is the demo

我希望在显示第一个/最后 3 个项目后立即隐藏下一个上一个按钮

const carousel = document.querySelector(".container5-carousel");
const firstDiv = carousel.querySelectorAll(".carousel-item")[0];
const carouselBtn = document.querySelectorAll(".carousel-button i");

let firstDivWidth = firstDiv.clientWidth + 14;
let scrollWidth = carousel.scrollWidth - carousel.clientWidth;

const showHideButton = () => {
  carouselBtn[0].style.display = carousel.scrollLeft == 0 ? "none" : "block";
  carouselBtn[1].style.display = carousel.scrollLeft == scrollWidth ? "none" : "block";
}

carouselBtn.forEach(btn => {
  btn.addEventListener("click", () => {
    if (btn.id == "prev") {
      carousel.scrollLeft -= firstDivWidth;
    } else {
      carousel.scrollLeft += firstDivWidth;
    }

    setTimeout(() => showHideButton(), 60);
  })
});
.container5 {
  width: 100%;
  margin: auto;
  align-items: center;
  background-color: #fdd8d8;
  padding: 2rem 0;
}

.container5-subcontainer {
  width: 100%;
  position: relative;
}

.carousel-wrapper {
  width: 80%;
  max-width: 1200px;
  height: fit-content;
  margin: 0 auto;
  position: relative;
  padding: 1rem 0;
}

.container5-carousel {
  margin: 0 auto;
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: calc((100%/3) - 2rem);
  overflow: hidden;
  padding: 2rem 0;
  gap: 3rem;
  white-space: nowrap;
  scroll-behavior: smooth;
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  scroll-padding: 0;
}

.carousel-item {
  border-radius: 15px;
  background-color: #ffffff;
  box-shadow: 0 -0.4rem 1rem 0.2rem rgba(0, 0, 0, 0.12);
  scroll-snap-align: center;
}

.carousel-button i {
  font-size: 1.5rem;
  color: #222222;
  width: 50px;
  height: 50px;
  line-height: 50px;
  text-align: center;
  border-radius: 50%;
  background-color: #ffffffc4;
  margin: 0;
  box-shadow: 3px 3px 9px 5px rgba(0, 0, 0, 0.12);
  position: absolute;
  min-width: 50px;
  min-height: 50px;
  cursor: pointer;
}

.carousel-button i:first-child {
  left: 0;
  display: none;
}

.carousel-button i:last-child {
  right: 0;
}
<div class="container5">
  <h1>Portfolio!</h1>
  <div class="container5-subcontainer">
    <div class="carousel-wrapper">
      <div class="carousel-button">
        <i id="prev" class="fa-solid fa-angle-left"></i>
        <i id="next" class="fa-solid fa-angle-right"></i>
      </div>

      <div class="container5-carousel">
        <div class="carousel-item">
          <img class="carousel-img" src="assets/img/sample2.jpg" alt="">
          <h2>Product Title</h2>
          <p>Lorem ipsum, dolor sit amet consectetur adipisicing elit. Accusantium recusandae deleniti voluptates pariatur modi illo corporis obcaecati repudiandae perferendis tempore dolor consequatur dolorem, alias magni id sequi libero amet eaque!</p>
        </div>
        <div class="carousel-item">
          <img class="carousel-img" src="assets/img/sample3.jpg" alt="">
          <h2>Product Title</h2>
          <p>Lorem ipsum, dolor sit amet consectetur adipisicing elit. Accusantium recusandae deleniti voluptates pariatur modi illo corporis obcaecati repudiandae perferendis tempore dolor consequatur dolorem, alias magni id sequi libero amet eaque!</p>
        </div>
        <div class="carousel-item">
          <img class="carousel-img" src="assets/img/sample4.jpg" alt="">
          <h2>Product Title</h2>
          <p>Lorem ipsum, dolor sit amet consectetur adipisicing elit. Accusantium recusandae deleniti voluptates pariatur modi illo corporis obcaecati repudiandae perferendis tempore dolor consequatur dolorem, alias magni id sequi libero amet eaque!</p>
        </div>
        <div class="carousel-item">
          <img class="carousel-img" src="assets/img/sample5.jpg" alt="">
          <h2>Product Title</h2>
          <p>Lorem ipsum, dolor sit amet consectetur adipisicing elit. Accusantium recusandae deleniti voluptates pariatur modi illo corporis obcaecati repudiandae perferendis tempore dolor consequatur dolorem, alias magni id sequi libero amet eaque!</p>
        </div>
        <div class="carousel-item">
          <img class="carousel-img" src="assets/img/sample6.jpg" alt="">
          <h2>Product Title</h2>
          <p>Lorem ipsum, dolor sit amet consectetur adipisicing elit. Accusantium recusandae deleniti voluptates pariatur modi illo corporis obcaecati repudiandae perferendis tempore dolor consequatur dolorem, alias magni id sequi libero amet eaque!</p>
        </div>
        <div class="carousel-item">
          <img class="carousel-img" src="assets/img/sample2.jpg" alt="">
          <h2>Product Title</h2>
          <p>Lorem ipsum, dolor sit amet consectetur adipisicing elit. Accusantium recusandae deleniti voluptates pariatur modi illo corporis obcaecati repudiandae perferendis tempore dolor consequatur dolorem, alias magni id sequi libero amet eaque!</p>
        </div>
        <div class="carousel-item">
          <img class="carousel-img" src="assets/img/sample3.jpg" alt="">
          <h2>Product Title</h2>
          <p>Lorem ipsum, dolor sit amet consectetur adipisicing elit. Accusantium recusandae deleniti voluptates pariatur modi illo corporis obcaecati repudiandae perferendis tempore dolor consequatur dolorem, alias magni id sequi libero amet eaque!</p>
        </div>
        <div class="carousel-item">
          <img class="carousel-img" src="assets/img/sample4.jpg" alt="">
          <h2>Product Title</h2>
          <p>Lorem ipsum, dolor sit amet consectetur adipisicing elit. Accusantium recusandae deleniti voluptates pariatur modi illo corporis obcaecati repudiandae perferendis tempore dolor consequatur dolorem, alias magni id sequi libero amet eaque!</p>
        </div>
        <div class="carousel-item">
          <img class="carousel-img" src="assets/img/sample5.jpg" alt="">
          <h2>Product Title</h2>
          <p>Lorem ipsum, dolor sit amet consectetur adipisicing elit. Accusantium recusandae deleniti voluptates pariatur modi illo corporis obcaecati repudiandae perferendis tempore dolor consequatur dolorem, alias magni id sequi libero amet eaque!</p>
        </div>
        <div class="carousel-item">
          <img class="carousel-img" src="assets/img/sample6.jpg" alt="">
          <h2>Product Title</h2>
          <p>Lorem ipsum, dolor sit amet consectetur adipisicing elit. Accusantium recusandae deleniti voluptates pariatur modi illo corporis obcaecati repudiandae perferendis tempore dolor consequatur dolorem, alias magni id sequi libero amet eaque!</p>
        </div>
        <div class="carousel-item">
          <img class="carousel-img" src="assets/img/sample2.jpg" alt="">
          <h2>Product Title</h2>
          <p>Lorem ipsum, dolor sit amet consectetur adipisicing elit. Accusantium recusandae deleniti voluptates pariatur modi illo corporis obcaecati repudiandae perferendis tempore dolor consequatur dolorem, alias magni id sequi libero amet eaque!</p>
        </div>
      </div>
      <div class="container5-vm flex-grow">
        <a class="content5-button" href="#">View More &rarr; </a>
      </div>
    </div>
  </div>
</div>

javascript button carousel scroll-snap
1个回答
0
投票

可以使用firstlast元素getBoundingClientRect().left并将其与窗口的scrollX相加,并与父级进行比较 getBoundingClientRect().left分别位置。

要检查第一个元素的位置,请查看元素

getBoundingClientRect().left
位置 +
window.scrollX
位置是否大于或等于父元素
getBoundingClientRect().left
位置。

要检查最后一个元素相对于其父节点的位置,只需为最后一个元素及其父节点添加 rect.leftrect.width,将最后一个元素的计算包装在 中Math.floor() 删除任何不需要的小数。

请参阅代码中的进一步说明。

如果有任何不清楚的地方或者这不是您想要的,请告诉我。

const carousel = document.querySelector(".container5-carousel");
// added to compare first and last of the carousel items
const carouselItem = carousel.querySelectorAll(".carousel-item");
const firstDiv = carousel.querySelectorAll(".carousel-item")[0];
const carouselBtn = document.querySelectorAll(".carousel-button i");

let firstDivWidth = firstDiv.clientWidth + 14;
let scrollWidth = carousel.scrollWidth - carousel.clientWidth;

const showHideButton = () => {
  // get the first element in the carousel-item node list 
  // and get its BoundingClientRect
  const firstItemRect = carouselItem[0].getBoundingClientRect();
  // get the last element in the carousel-item node list
  // using carouselItem[carouselItem.length-1]
  // and get its BoundingClientRect
  const lastItemRect = carouselItem[carouselItem.length-1].getBoundingClientRect();
  // parents boundingClientRect()
  const contRect = carousel.getBoundingClientRect();
  // compare the windows scrollX position + the position of the element rect.left position
  // in relation to the parent elements rect.left position
  firstItemRect.left + window.scrollX >= contRect.left ? 
    carouselBtn[0].style.display = "none" :
    carouselBtn[0].style.display = "block";
  // use Math.floor to round to lowest whole
  // get the last elements rect left + its width + window scrollX position and compare
  // to the parents rect.left + rect.width
  Math.floor(lastItemRect.left + lastItemRect.width + window.scrollX) <= contRect.left + contRect.width ? 
    carouselBtn[1].style.display = "none" :
    carouselBtn[1].style.display = "block";
}

carouselBtn.forEach(btn => {
  btn.addEventListener("click", () => {
    if (btn.id == "prev") {
      carousel.scrollLeft -= firstDivWidth;
    } else {
      carousel.scrollLeft += firstDivWidth;
    }
  })
});

// eventListener for scroll on the parent element
carousel.addEventListener('scroll', showHideButton)
.container5 {
  width: 100%;
  margin: auto;
  align-items: center;
  background-color: #fdd8d8;
  padding: 2rem 0;
}

.container5-subcontainer {
  width: 100%;
  position: relative;
}

.carousel-wrapper {
  width: 80%;
  max-width: 1200px;
  height: fit-content;
  margin: 0 auto;
  position: relative;
  padding: 1rem 0;
}

.container5-carousel {
  margin: 0 auto;
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: calc((100%/3) - 2rem);
  overflow: hidden;
  padding: 2rem 0;
  gap: 3rem;
  white-space: nowrap;
  scroll-behavior: smooth;
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  scroll-padding: 0;
}

.carousel-item {
  border-radius: 15px;
  background-color: #ffffff;
  box-shadow: 0 -0.4rem 1rem 0.2rem rgba(0, 0, 0, 0.12);
  scroll-snap-align: center;
}

.carousel-button i {
  font-size: 1.5rem;
  color: #222222;
  width: 50px;
  height: 50px;
  line-height: 50px;
  text-align: center;
  border-radius: 50%;
  background-color: #ffffffc4;
  margin: 0;
  box-shadow: 3px 3px 9px 5px rgba(0, 0, 0, 0.12);
  position: absolute;
  min-width: 50px;
  min-height: 50px;
  cursor: pointer;
}

.carousel-button i:first-child {
  left: 0;
  display: none;
}

.carousel-button i:last-child {
  right: 0;
}

/* added css rule to remove any text overflow */
.carousel-item p {
  overflow-x: hidden;
}
<div class="container5">
  <!--<h1>Portfolio!</h1> removed for demo -->
  <div class="container5-subcontainer">
    <div class="carousel-wrapper">
      <div class="carousel-button">
        <i id="prev" class="fa-solid fa-angle-left"></i>
        <i id="next" class="fa-solid fa-angle-right"></i>
      </div>

      <div class="container5-carousel">
        <div class="carousel-item">
          <img class="carousel-img" src="assets/img/sample2.jpg" alt="">
          <h2>Product Title</h2>
          <p>Lorem ipsum, dolor sit amet consectetur adipisicing elit. Accusantium recusandae deleniti voluptates pariatur modi illo corporis obcaecati repudiandae perferendis tempore dolor consequatur dolorem, alias magni id sequi libero amet eaque!</p>
        </div>
        <div class="carousel-item">
          <img class="carousel-img" src="assets/img/sample3.jpg" alt="">
          <h2>Product Title</h2>
          <p>Lorem ipsum, dolor sit amet consectetur.</p>
        </div>
        <div class="carousel-item">
          <img class="carousel-img" src="assets/img/sample4.jpg" alt="">
          <h2>Product Title</h2>
          <p>Lorem ipsum, dolor sit amet consectetur adipisicing elit.</p>
        </div>
        <div class="carousel-item">
          <img class="carousel-img" src="assets/img/sample5.jpg" alt="">
          <h2>Product Title</h2>
          <p>Lorem ipsum, dolor sit amet consectetur adipisicing elit.</p>
        </div>
        <div class="carousel-item">
          <img class="carousel-img" src="assets/img/sample6.jpg" alt="">
          <h2>Product Title</h2>
          <p>Lorem ipsum, dolor sit amet consectetur adipisicing elit.</p>
        </div>
        <div class="carousel-item">
          <img class="carousel-img" src="assets/img/sample2.jpg" alt="">
          <h2>Product Title</h2>
          <p>Lorem ipsum, dolor sit amet consectetur adipisicing elit.</p>
        </div>
        <div class="carousel-item">
          <img class="carousel-img" src="assets/img/sample3.jpg" alt="">
          <h2>Product Title</h2>
          <p>Lorem ipsum, dolor sit amet consectetur adipisicing elit.</p>
        </div>
        <div class="carousel-item">
          <img class="carousel-img" src="assets/img/sample4.jpg" alt="">
          <h2>Product Title</h2>
          <p>Lorem ipsum, dolor sit amet consectetur adipisicing elit.</p>
        </div>
        <div class="carousel-item">
          <img class="carousel-img" src="assets/img/sample5.jpg" alt="">
          <h2>Product Title</h2>
          <p>Lorem ipsum, dolor sit amet consectetur adipisicing elit.</p>
        </div>
        <div class="carousel-item">
          <img class="carousel-img" src="assets/img/sample6.jpg" alt="">
          <h2>Product Title</h2>
          <p>Lorem ipsum, dolor sit amet consectetur adipisicing elit.</p>
        </div>
        <div class="carousel-item">
          <img class="carousel-img" src="assets/img/sample2.jpg" alt="">
          <h2>Product Title</h2>
          <p>This is the last item.</p>
        </div>
      </div>
      <div class="container5-vm flex-grow">
        <a class="content5-button" href="#">View More &rarr; </a>
      </div>
    </div>
  </div>
</div>

© www.soinside.com 2019 - 2024. All rights reserved.