当页面滚动到底部时,JavaScript scroll()事件无限循环

时间:2019-10-23 16:35:22

标签: javascript jquery html

我制作了一个页面,当用户滚动页面时,一旦到达窗口,每个div就会被动画化。我使用jQuery处理scroll()事件。

我的动画更改了divs的宽度。问题是当我到达页面末尾时,发生了奇怪的事情:scroll()事件是由自身以无限循环触发的,每次都将页面向上滚动一点。如何解决?

<html>
<head>
    <meta charset="UTF-8">
    <script src="jquery-3.3.1.min.js"></script>
</head>
<body>

<div class='fadein' data-fadewidth='1em' id='1'>
Div 1
Long text so that the animation can be seen
</div>

<div class='fadein' data-fadewidth='2em' id='2'>
Div 2
Long text so that the animation can be seen
</div>

<div class='fadein' data-fadewidth='3em' id='3'>
Div 3
Long text so that the animation can be seen
</div>

<div class='fadein' data-fadewidth='4em' id='4'>
Div 4
Long text so that the animation can be seen
</div>

<div class='fadein' data-fadewidth='5em' id='5'>
Div 5
Long text so that the animation can be seen
</div>

<br/>

<style>
div {
    margin-bottom: 30%;
}
</style>

<script>

$(document).ready(function() {

    var refresh = function(cls) {

        $(cls).each( function(el) {
            var bottom_of_object = $(this).offset().top + $(this).outerHeight();
            var bottom_of_window = $(window).scrollTop() + $(window).height();

            var delay = 0;
            var time = 2000;

            var animation = {};

            if ($(this).data('fadewidth') != undefined) {
                animation.width = $(this).data('fadewidth');
            }

            if( bottom_of_window > bottom_of_object - ($(window).height()*0.25) ) {

                setTimeout(function () {
                    $(this).animate(animation, time);
                }.bind(this), delay);

            }
        });
    };

    $(window).scroll(function() {
        console.log(Date(), ' page scrolled ');
        refresh('.fadein')});

    refresh('.fadein');

});

</script>

</body>
</html>

在以下行为中测试了描述的行为:GNU / Linux 4.19.69-1-MANJARO上的Firefox 69.0.3和Chromium 77.0.3865.120

1 个答案:

答案 0 :(得分:0)

我稍微更改了您的代码。这是您的script标签的内容:

<script>

$(document).ready(function() {

    var scrollHandler = function () {
        console.log(Date(), ' page scrolled ');
        refresh('.fadein');
    };

    function refresh(cls) {

        if ((window.innerHeight + window.scrollY) >= document.body.offsetHeight) {
            // you're at the bottom of the page, so remove the event handler.
            $(window).off("scroll", scrollHandler);
        }
        $(cls).each( function(el) {
            var bottom_of_object = $(this).offset().top + $(this).outerHeight();
            var bottom_of_window = $(window).scrollTop() + $(window).height();

            var delay = 0;
            var time = 2000;

            var animation = {};

            if ($(this).data('fadewidth') != undefined) {
                animation.width = $(this).data('fadewidth');
            }

            if( bottom_of_window > bottom_of_object - ($(window).height()*0.25) ) {

                setTimeout(function () {
                    $(this).animate(animation, time);
                }.bind(this), delay);

            }
        });
    };



    $(window).scroll(scrollHandler);


    refresh('.fadein');

});

</script>

当用户滚动条到达页面底部时,我将删除事件处理程序。

但是您的代码仍然存在一些问题:

if( bottom_of_window > bottom_of_object - ($(window).height()*0.25) ) {

    setTimeout(function () {
        $(this).animate(animation, time);
    }.bind(this), delay);

}

您在此设置的动画次数太多,以至于即使用户触底并删除事件处理程序,仍然会执行动画。

发生这种情况是因为您已经设置了它们。因此,如果等待一段时间,当所有命令执行完毕后,页面将停止向上滚动。

请注意这一点,并更改设置动画的方式,使其仅一次执行一次div。