admin管理员组文章数量:1122846
I'm trying to make carousel with 3 items displayed that the width scales of 100%/3 of its parent.
The next prev button works fine and the show-hide function works well if only they reach the edge of the element [0] and [1].
If I start from [0] the prev button still hidden and when I press the next button, the item will be scrolled perfectly and the prev button will be shown, but when I reach the last item the next button doesn't hide immediately unless I press once again, then it will be hidden, same as the prev button, if I go back to the first element it won't immediately hidden, unless I press once again.
I want the next prev button to be hidden as soon as I have displayed the first/last 3 items
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 → </a>
</div>
</div>
</div>
</div>
I'm trying to make carousel with 3 items displayed that the width scales of 100%/3 of its parent.
The next prev button works fine and the show-hide function works well if only they reach the edge of the element [0] and [1].
If I start from [0] the prev button still hidden and when I press the next button, the item will be scrolled perfectly and the prev button will be shown, but when I reach the last item the next button doesn't hide immediately unless I press once again, then it will be hidden, same as the prev button, if I go back to the first element it won't immediately hidden, unless I press once again.
I want the next prev button to be hidden as soon as I have displayed the first/last 3 items
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 → </a>
</div>
</div>
</div>
</div>
Share
Improve this question
edited Nov 21, 2024 at 17:35
mplungjan
177k28 gold badges180 silver badges240 bronze badges
asked Nov 21, 2024 at 17:29
marsel herdianmarsel herdian
31 bronze badge
1
- I made you a snippet. Please click edit, then scroll down and click "edit above snippet" and add relevant frameworks or functions from CDN – mplungjan Commented Nov 21, 2024 at 17:36
1 Answer
Reset to default 0You could use the first and last elements getBoundingClientRect().left and add that with the scrollX of the window and compare that with the parents getBoundingClientRect().left positions respectively.
To check the first elements position see if the elements getBoundingClientRect().left
position + the window.scrollX
position is greater than or equal to the parents getBoundingClientRect().left
position.
To check the last elements position relative to its parent, just add the getBoundingClientRect().left
+ getBoundingClientRect().width
+ window.scrollX
for the last elements position and then compare it to the getBoundingClientRect().left
+ getBoundingClientRect().width
on the parentNode, wrap the last elements calculation in Math.floor() to remove any unwanted decimals. Set the style appropriately within the conditionals.
I added the showHideButton method to a scroll eventListener on the parent element.
Note: Moved firstDiv, firstDivWidth, and scrollWidth into the btn eventListener methods scope, in case you expand the size of the page after the page loads and caches the clientWidth of firstDiv
. This way when you press the button it will query that element then and get its current clientWidth.
See further explanation in the code.
Let me know if anything is unclear or if this is not what you were looking for.
const carouselBtn = document.querySelectorAll(".carousel-button i");
const carousel = document.querySelector(".container5-carousel");
const showHideButton = (e) => {
const carouselItem = e.target.querySelectorAll(".carousel-item");
// 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 = e.target.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";
}
const slideElement = (e) => {
// moved the following three variables into btn event scope
const firstDiv = carousel.querySelectorAll(".carousel-item")[0];
let firstDivWidth = firstDiv.clientWidth + 14;
let scrollWidth = carousel.scrollWidth - carousel.clientWidth;
if (e.target.id == "prev") {
carousel.scrollLeft -= firstDivWidth;
} else {
carousel.scrollLeft += firstDivWidth;
}
}
carouselBtn.forEach(btn => {
btn.addEventListener("click", slideElement);
});
// 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 → </a>
</div>
</div>
</div>
</div>
版权声明:本文标题:javascript - nextprev button not hiding when reaching firstlast element using scroll-snap-align - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1736308464a1933671.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论