gpt4 book ai didi

javascript - 带有导航(下一个,上一个)按钮的 CSS 滚动捕捉点

转载 作者:行者123 更新时间:2023-11-29 15:08:23 24 4
gpt4 key购买 nike

我正在构建一个旋转木马,非常简约,使用 CSS snap points 。拥有纯 CSS 选项对我来说很重要,但我可以使用 javascript(无框架)增强一点。 p>

我正在尝试添加上一个和下一个按钮 以编程方式滚动到下一个或上一个元素。如果禁用 javascript,按钮将被隐藏,轮播仍然可用。

我的问题是关于如何触发滚动到下一个捕捉点

所有元素都有不同的大小,我发现大多数解决方案需要像素值(例如示例中使用的scrollBy)。 scrollBy 40px适用于第 2 页,但不适用于其他页面,因为它们太大(尺寸基于视口(viewport))。

function goPrecious() {
document.getElementById('container').scrollBy({
top: -40,
behavior: 'smooth'
});
}

function goNext() {
document.getElementById('container').scrollBy({
top: 40,
behavior: 'smooth'
});
}
#container {
scroll-snap-type: y mandatory;
overflow-y: scroll;

border: 2px solid var(--gs0);
border-radius: 8px;
height: 60vh;
}

#container div {
scroll-snap-align: start;

display: flex;
justify-content: center;
align-items: center;
font-size: 4rem;
}
#container div:nth-child(1) {
background: hotpink;
color: white;
height: 50vh;
}
#container div:nth-child(2) {
background: azure;
height: 40vh;
}
#container div:nth-child(3) {
background: blanchedalmond;
height: 60vh;
}
#container div:nth-child(4) {
background: lightcoral;
color: white;
height: 40vh;
}
<div id="container">
<div>1</div>
<div>2</div>
<div>3</div>
<div>4</div>
</div>

<button onClick="goPrecious()">previous</button>
<button onClick="goNext()">next</button>

最佳答案

好问题!我把这当作一个挑战。
所以,我增加了JavaScript使其动态工作。按照我的详细解决方案(最后是完整代码):

首先,添加position: relative.container , 因为它需要作为 scroll 的引用和 height内部检查 .container .

然后,让我们创建3个全局辅助variables :

1) 一次获得元素scroll positions (顶部和底部)为 arrays进入 array .示例:[[0, 125], [125, 280], [280, 360]] (本例中为 3 项)。
3) 存储 .container height 一半的一个(以后会有用)
2) 另一个存储item index对于 scroll位置

var carouselPositions;
var halfContainer;
var currentItem;

现在,一个 function称为 getCarouselPositions创建 array与元素位置(存储在 carouselPositions 中)并计算 .container 的一半(存储在 halfContainer 中):

function getCarouselPositions() {
carouselPositions = [];
document.querySelectorAll('#container div').forEach(function(div) {
carouselPositions.push([div.offsetTop, div.offsetTop + div.offsetHeight]); // add to array the positions information
})
halfContainer = document.querySelector('#container').offsetHeight/2;
}

getCarouselPositions(); // call it once

让我们替换 functionsbuttons .现在,当你点击它们时,相同的 function将被调用,但带有 "next""previous"参数:

<button onClick="goCarousel('previous')">previous</button>
<button onClick="goCarousel('next')">next</button>

这里是关于 goCarousel function本身:

首先,它创建 2 variables那家店top scroll位置和bottom scroll旋转木马的位置。

然后,有2个条件判断当前轮播位置是否在最top上或大多数 bottom .
如果它在 top然后点击"next" button ,它将转到第二个元素位置。如果它在 bottom然后点击"previous" button , 它将转到最后一项之前的前一项。

如果两个条件都失败,则表示当前项不是第一个或最后一个。因此,它会检查 current position 是什么,使用 array of positions 循环使用容器的一半进行计算看什么item正在显示。然后,它与 "previous" 结合或 "next"检查为 currentItem 设置正确的下一个位置变量。

最后通过scrollTo走到正确的位置使用 currentItem新值(value)。

完整代码如下:

var carouselPositions;
var halfContainer;
var currentItem;

function getCarouselPositions() {
carouselPositions = [];
document.querySelectorAll('#container div').forEach(function(div) {
carouselPositions.push([div.offsetTop, div.offsetTop + div.offsetHeight]); // add to array the positions information
})
halfContainer = document.querySelector('#container').offsetHeight/2;
}

getCarouselPositions(); // call it once

function goCarousel(direction) {

var currentScrollTop = document.querySelector('#container').scrollTop;
var currentScrollBottom = currentScrollTop + document.querySelector('#container').offsetHeight;

if (currentScrollTop === 0 && direction === 'next') {
currentItem = 1;
} else if (currentScrollBottom === document.querySelector('#container').scrollHeight && direction === 'previous') {
console.log('here')
currentItem = carouselPositions.length - 2;
} else {
var currentMiddlePosition = currentScrollTop + halfContainer;
for (var i = 0; i < carouselPositions.length; i++) {
if (currentMiddlePosition > carouselPositions[i][0] && currentMiddlePosition < carouselPositions[i][1]) {
currentItem = i;
if (direction === 'next') {
currentItem++;
} else if (direction === 'previous') {
currentItem--
}
}
}
}

document.getElementById('container').scrollTo({
top: carouselPositions[currentItem][0],
behavior: 'smooth'
});

}
window.addEventListener('resize', getCarouselPositions);
#container {
scroll-snap-type: y mandatory;
overflow-y: scroll;
border: 2px solid var(--gs0);
border-radius: 8px;
height: 60vh;
position: relative;
}

#container div {
scroll-snap-align: start;

display: flex;
justify-content: center;
align-items: center;
font-size: 4rem;
}
#container div:nth-child(1) {
background: hotpink;
color: white;
height: 50vh;
}
#container div:nth-child(2) {
background: azure;
height: 40vh;
}
#container div:nth-child(3) {
background: blanchedalmond;
height: 60vh;
}
#container div:nth-child(4) {
background: lightcoral;
color: white;
height: 40vh;
}
<div id="container">
<div>1</div>
<div>2</div>
<div>3</div>
<div>4</div>
</div>

<button onClick="goCarousel('previous')">previous</button>
<button onClick="goCarousel('next')">next</button>

要添加的另一个好细节是调用 getCarouselPositions如果窗口调整大小再次运行:

window.addEventListener('resize', getCarouselPositions);

就是这样。
这样做很酷。我希望它能以某种方式提供帮助。

关于javascript - 带有导航(下一个,上一个)按钮的 CSS 滚动捕捉点,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57518428/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com