我目前在下面可以看到一些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;
}
如果有人能给我任何解决问题的想法,那就太棒了。
答案 0 :(得分:1)
您需要停止活动并阻止默认。以下是当前着陆页中的一些代码:
$(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()
来阻止滚动事件冒泡,从而变为递归。
编辑:
O.k。所以我有一个更好的外观和基本问题:无限滚动是代码不检查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上与用户保持滚动。即你的代码会让它跳回到以前的位置。
答案 1 :(得分:1)
尝试将scroll
事件处理程序定义为命名函数;在lastScrollTop
处理程序之外定义scroll
;将.one()
替换为.on()
以允许动画在重新附加scroll
事件之前完成;使用最多应调用一次的.promise()
,以避免使用选择器.animate()
调用complete
"html, body"
次回调。替换单if
来检查下一个或上一个元素.length
和.animate()
是否需要调用多个if..else
条件和语句,动画函数调用;动画完成scroll
.then()
重新附加.promise()
个事件
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>