[英]Having trouble getting the scroll animation to not trigger the scroll event
我目前有许多 div 标签,可以在下面看到,每个标签都是视口的高度。
<!-- .current represents the div the user is currently viewing -->
<div class="full-height current" id="id1">
<div class="container">
</div>
</div>
<div class="full-height" id="id2">
<div class="container">
</div>
</div>
<div class="full-height" id="id3">
<div class="container">
</div>
</div>
<div class="full-height" id="id4">
<div class="container">
</div>
</div>
<div class="full-height" id="id5">
<div class="container">
</div>
</div>
我正在尝试实现一项功能,在用户滚动时,窗口将滚动到下一个 div 标记,一次始终只有一个 div 可见。 我实现它的方式非常有效,除了动画再次触发滚动事件之外,一旦用户完全滚动,就会导致页面滚动无限循环。 我试图通过设置一个变量来解决此问题,如果动画正在进行,该变量将停止触发事件,但它似乎不起作用。 我知道我没有为向上滚动而这样做,但我只是想先看看它是否适用于向下滚动。
$(window).scroll(function(event) {
var scrollTop = $(this).scrollTop();
// If user scrolls down
if ((scrollTop > lastScrollTop) && $(".current").next("div").length > 0) {
if (animating == false) {
console.log("down");
$(".current").next("div").addClass("current");
$(".current").first().removeClass("current");
animating = true;
$("html, body").animate({
scrollTop: $(".current").offset().top
}, 1000, function() {animating = false});
}
// If user scrolls up
} else {
if ($(".current").prev("div").length > 0) {
console.log("up");
$(".current").prev("div").addClass("current");
$(".current").last().removeClass("current");
$("html, body").animate({
scrollTop: $(".current").offset().top
}, 1000);
}
}
lastScrollTop = scrollTop;
});
包含 CSS 以防万一。 100vh - 111px 是由于顶部的固定导航栏高 111px
/* Makes the element take up the entire height of the screen */
.full-height{
height: -o-calc(100vh - 111px); /* opera */
height: -webkit-calc(100vh - 111px); /* google, safari */
height: -moz-calc(100vh - 111px); /* firefox */
}
#id1 {
background-color: red;
}
#id2 {
background-color: blue;
}
#id3 {
background-color: yellow;
}
#id4 {
background-color: green;
}
#id5 {
background-color: purple;
}
如果有人能给我任何解决问题的想法,那就太好了。
您需要停止事件并阻止默认。 以下是当前着陆页中的一些代码:
$(document).ready(function () {
$('a.page-scroll').on('click', function(event) {
var link = $(this);
$('html, body').stop().animate({
scrollTop: $(link.attr('href')).offset().top - 50
}, 500);
event.preventDefault();
});
$('body').scrollspy({
target: '.navbar-fixed-top',
offset: 80
});
});
它使用 bootstrap scrollspy 所以忽略它。 但请注意,它会停止任何可能正在运行的滚动动画,然后还会调用event.preventDefault()
来阻止滚动事件冒泡并因此变得递归。
编辑:
好的,所以我有一个更好的外观和基本问题:无限滚动是代码不检查 scrollTop 是否已经在“它需要的地方”。 您需要额外检查以使卷轴短路:
if (animating == false) {
if ($(this).scrollTop() == lastScrollTop) return;
if (($(this).scrollTop() > lastScrollTop) && $(".current").next("div")) {
console.log("down");
$(".current").next("div").addClass("current");
$(".current").first().removeClass("current");
animating = true;
$("html, body").stop().animate({
scrollTop: $(".current").offset().top
}, 1000,
function () { lastScrollTop = $(this).scrollTop(); animating = false; });
// If user scrolls up
} else {
if ($(".current").prev("div").length > 0) {
console.log("up");
$(".current").prev("div").addClass("current");
$(".current").last().removeClass("current");
$("html, body").stop().animate({
scrollTop: $(".current").offset().top
}, 1000, function () { lastScrollTop = $(this).scrollTop(); animating = false; });
}
}
}
否则,就目前而言,它将始终向上或向下滚动并且永远不会稳定下来。 也就是说,“工作”是一种糟糕的用户体验。 它会跳来跳去,因为如果用户继续滚动,您滚动到代码会在当前 scrollTop 上与用户发生冲突。 即您的代码将使它跳回到以前的位置。
尝试将scroll
事件处理程序定义为命名函数; 在scroll
处理程序之外定义lastScrollTop
; 将.one()
替换为.on()
以允许动画在重新附加scroll
事件之前完成; 使用.promise()
最多调用一次以避免.animate()
complete
回调被选择器"html, body"
调用两次; 替换单个if
来检查下一个或前一个元素.length
和.animate()
调用多个if..else
条件和语句,动画函数调用; 在动画完成.promise()
.then()
在 .then() 重新附加scroll
事件
var lastScrollTop = 0; function scroller(event) { var scrollTop = $(this).scrollTop(); var direction = scrollTop > lastScrollTop? "next": "prev"; var el = $(".current")[direction](".full-height"); console.log(direction === "next"? "down": "up"); if (el.is("*")) { $("html, body").animate({ scrollTop: el.offset().top }, 1000).promise().then(function() { console.log(this) lastScrollTop = $(window).scrollTop(); $(".current").removeClass("current")[direction]("div").addClass("current") setTimeout(function() { $(window).one("scroll", scroller) }) }); } else { lastScrollTop = scrollTop; $(window).one("scroll", scroller) } } $(window).one("scroll", scroller);
/* Makes the element take up the entire height of the screen */.full-height { height: -o-calc(100vh - 111px); /* opera */ height: -webkit-calc(100vh - 111px); /* google, safari */ height: -moz-calc(100vh - 111px); /* firefox */ } #id1 { background-color: red; } #id2 { background-color: blue; } #id3 { background-color: yellow; } #id4 { background-color: green; } #id5 { background-color: purple; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script> <.-- .current represents the div the user is currently viewing --> <div class="full-height current" id="id1"> <div class="container"> </div> </div> <div class="full-height" id="id2"> <div class="container"> </div> </div> <div class="full-height" id="id3"> <div class="container"> </div> </div> <div class="full-height" id="id4"> <div class="container"> </div> </div> <div class="full-height" id="id5"> <div class="container"> </div> </div>
如果您定义高度 100vh,滚动事件将不会触发
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.