gpt4 book ai didi

javascript - 当元素进入视口(viewport)时,在离开视口(viewport)之前水平滚动其全部内容

转载 作者:太空狗 更新时间:2023-10-29 14:18:41 24 4
gpt4 key购买 nike

我有一个水平滚动元素,其中包含位于页面下方 View 之外的图像。

首先,我有以下标记和样式。我使用了 overflow:hidden 因为我不想要滚动条。为了简单起见,我还删除了一些不太重要的样式:

<ul id="players-horizontal">
<li class="player-box"><img src="..."></li>
<li class="player-box"><img src="..."></li>
...
</ul>

#players-horizontal {
overflow: hidden;
height: 340px;
width: 100%;
}

#players-horizontal .player-box {
display: inline-block;
width: 300px;
height: 340px;
}

#players-horizontal .player-box:first-child {
margin-left: 90%;
}

这给了我以下观点:

enter image description here

当这个元素滚动到 View 中时,我想水平滚动它的全部内容直到它即将离开 View ,这样用户可以在向下滚动的同时看到它的全部内容。

当元素即将离开视口(viewport)时,所需的外观将是:

enter image description here

反之亦然,当用户向上滚动时应该发生相反的 Action 。

要知道元素何时进入视口(viewport),我使用了 Waypoints插件:

var waypoints = $('#players-horizontal').waypoint(
function(direction) {
if (direction === 'down') {
//console.log("Into view");
$window.scroll(function () {
var s = $(this).scrollTop();

});
} else {
//console.log("Out of view");
$window.scroll(function () {
var s = $(this).scrollTop();

});
}
}, { offset: '90%' }
);

但我仍然无法理解下一步该做什么,更具体地说,如何计算出在元素离开视口(viewport)之前的短时间内滚动(改变边距)多少,确保其中的所有元素在它之前显示。

如果能在终点线上提供帮助,我将不胜感激。我不期望工作代码,虽然我很感激,但我真的只需要一个简单易懂的解释来说明需要什么。

更新:

我刚刚尝试使用另一种方法,该方法不使用 Waypoints 插件而是使用 ScrollMagic .这无疑减轻了很多所需的工作。

var scene = new ScrollMagic.Scene({triggerElement: "#players-horizontal", duration: 200})
.addTo(controller)
.on("progress", function (e) {
console.log((e.progress * 100));
});

上面的代码片段检测元素 #players-horizo​​ntal 何时进入和离开视口(viewport)。

当元素在向下滚动时进入视口(viewport)底部时,返回值从 0 开始,在离开视口(viewport)顶部之前停止在 100。当我向上滚动时,该值从 100 开始,当元素即将离开视口(viewport)底部时停止在 0。所以,我肯定更接近了。

最佳答案

我会以不同的方式考虑这个问题。首先我会考虑使用翻译使其更容易处理。你还需要一些 JS 代码来处理这个

我将有一个主容器,我将通过 90% 进行翻译以产生边距效果,然后我会将其中的内容从 0% 翻译为 100%。翻译将考虑滚动和屏幕高度。基本上,当元素进入屏幕时,我将开始翻译,考虑偏移顶部和屏幕高度之间的差异。

这是第一个例子。

var h =document.querySelector('#players-horizontal');

document.body.onscroll = function(e) {

var offset = h.getBoundingClientRect()
var top = offset.top;
if(top < window.innerHeight) {
h.style.setProperty('--x',(top - window.innerHeight)+'%');
}
}
body {
margin:0;
overflow-x:hidden;
}
.top,.bottom {
min-height:150vh;
background:yellow;
}
.container {
transform:translateX(90%);
}
#players-horizontal {
white-space:nowrap;
margin:0;
padding:0;
display:inline-block; /*This is important !!*/
transform:translateX(var(--x,0%));
border:5px solid;
}

#players-horizontal .player-box {
display: inline-block;
width: 200px;
height: 240px;
margin:0 10px;
background:red;
}

#players-horizontal .player-box:first-child {
background:green;
margin-left:0;
}
#players-horizontal .player-box:last-child {
background:blue;
margin-right:0;
}
<div class="top"></div>
<div class="container">
<ul id="players-horizontal">
<li class="player-box"></li>
<li class="player-box"></li>
<li class="player-box"></li>
<li class="player-box"></li>
<li class="player-box"></li>
</ul>
</div>
<div class="bottom"></div>

上面的内容将创建滚动效果,但现在我们需要定义正确的值。

很明显,我们需要在 top = window.innerHeight (translate(0%)) 和 top = 0 开始滚动> 我们希望我们的元素完全显示,最后一个元素在右边缘,这意味着我们需要 translate(-100% + width of screen) 但是因为屏幕的宽度也是与容器宽度相同,并且我们已经将容器翻译了 90% 那么我们只能达到 translate(-100%) (我们可以在最后添加负边距元素来纠正位置)

我们只需要将差值 (top - window.innerHeight) 转换为百分比值,将 window.innerHeight 视为 100% (当 top=0 时)。

var h =document.querySelector('#players-horizontal');

document.body.onscroll = function(e) {

var offset = h.getBoundingClientRect()
var top = offset.top;
if(top < window.innerHeight && top >=0) {
h.style.setProperty('--x',(top - window.innerHeight)*(100/window.innerHeight)+'%');
}
}
body {
margin:0;
overflow-x:hidden;
}
.top,.bottom {
min-height:150vh;
background:yellow;
}
.container {
transform:translateX(90%);
}
#players-horizontal {
white-space:nowrap;
margin:0;
padding:0;
display:inline-block; /*This is important !!*/
transform:translateX(var(--x,0%));
border:5px solid;
}

#players-horizontal .player-box {
display: inline-block;
width: 200px;
height: 240px;
margin:0 10px;
background:red;
vertical-align:top;
}

#players-horizontal .player-box:first-child {
background:green;
margin-left:0;
}
#players-horizontal .player-box:last-child {
background:blue;
margin-right:-10vw; /*the missing 10%*/
}
<div class="top"></div>
<div class="container">
<ul id="players-horizontal">
<li class="player-box"></li>
<li class="player-box"></li>
<li class="player-box"></li>
<li class="player-box"></li>
<li class="player-box"></li>
<li class="player-box"></li>
<li class="player-box"></li>
<li class="player-box"></li>
</ul>
</div>
<div class="bottom"></div>

我使用了 CSS 变量(个人偏好),但这并不是强制性的,您可以简单地使用 JS 代码设置转换:

var h =document.querySelector('#players-horizontal');

document.body.onscroll = function(e) {

var offset = h.getBoundingClientRect()
var top = offset.top;
if(top < window.innerHeight && top >=0) {
h.style.transform="translateX("+(top - window.innerHeight)*(100/window.innerHeight)+'%)';
}
}
body {
margin:0;
overflow-x:hidden;
}
.top,.bottom {
min-height:150vh;
background:yellow;
}
.container {
transform:translateX(90%);
}
#players-horizontal {
white-space:nowrap;
margin:0;
padding:0;
display:inline-block; /*This is important !!*/
transform:translateX(0%);
border:5px solid;
}

#players-horizontal .player-box {
display: inline-block;
width: 200px;
height: 240px;
margin:0 10px;
background:red;
vertical-align:top;
}

#players-horizontal .player-box:first-child {
background:green;
margin-left:0;
}
#players-horizontal .player-box:last-child {
background:blue;
margin-right:-10vw;
}
<div class="top"></div>
<div class="container">
<ul id="players-horizontal">
<li class="player-box"></li>
<li class="player-box"></li>
<li class="player-box"></li>
<li class="player-box"></li>
<li class="player-box"></li>
<li class="player-box"></li>
<li class="player-box"></li>
<li class="player-box"></li>
</ul>
</div>
<div class="bottom"></div>

关于javascript - 当元素进入视口(viewport)时,在离开视口(viewport)之前水平滚动其全部内容,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54419901/

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