繁体   English   中英

无法让滚动动画不触发滚动事件

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM