【问题标题】:How to call a function after scroll has ended?滚动结束后如何调用函数?
【发布时间】:2011-04-01 15:34:24
【问题描述】:

我想在滚动结束后立即调用一个函数。我尝试了 load 各种不同的东西,但都没有奏效,然后我在 SO 中找到了这个解决方案:

How do I know when I've stopped scrolling Javascript

我仔细查看了第二个答案并尝试了它 - 它有效。然后我试着为了我的目的稍微改变它。所以现在整个shebang看起来像这样:

<!DOCTYPE html>
<html>

<head>
<meta content="text/html; charset=utf-8" http-equiv="Content-Type">
<title>Do something after scroll ends</title>

<style type="text/css">
    #scrollableDiv{
        width:500px;
        height:100px;
        overflow:scroll;
    }

    #someContent{
        width:600px;
        height:200px;
    }
</style>

<script type="text/javascript" src="scripts/jquery-1.5.1-min.js"></script>

<script type="text/javascript">
    $(document).ready(function() {

        $('#scrollableDiv').bind('scroll', bodyScroll);

        var scrollTimer = -1;

        function bodyScroll() {
            console.log('scrolling.');

            if (scrollTimer != -1)
                clearTimeout(scrollTimer);

            scrollTimer = window.setTimeout('scrollEnded()', 500);

        };

        function scrollEnded(){
            console.log('scrollEnded. Now do something astounding.');
        };

    });
</script>

</head>

<body>

<div id="scrollableDiv">
    <div id="someContent">
        Scroll me.  
    </div>
</div>

</body>
</html>

当我运行它时,会触发滚动事件(太棒了!)。

然后,不是调用我的“scrollEnded()”函数,而是生成一个错误:“scrollEnded 未定义”。我试图通过进入调试模式并单步执行脚本来弄清楚这是从哪里来的,但随后我进入了一个“匿名函数”——这是我目前对这个问题的理解的极限。我尝试将 scrollEnded() 函数移到顶部。我已经尝试了各种各样的东西......

我可以做些什么来完成这项工作? (可以这个东西工作吗?)

【问题讨论】:

  • 请不要将字符串传递给setTimeoutsetInterval。是变相的eval,每次你eval,忍者都会杀死一只可爱的小动物。

标签: javascript jquery scroll


【解决方案1】:

作为所有这些答案的补充,我只建议设置 200 毫秒超时而不是 500。200 毫秒是手指移动和期望看到效果的眼睛之间的平均人眼反应。 200 毫秒的超时时间应该足够短, 不会被用户注意到,也应该足够长,以便 javascript 触发并完成事件。 我之前尝试过 200 毫秒,它似乎工作得很好,即使在速度较慢的 PC 上也是如此。

【讨论】:

    【解决方案2】:

    jQuery throttle/debounce plugin 非常适合这个。最后使用at_begin = false执行回调。

    var scrollEnded = $.debounce(500, false, function ()
    {
        console.log('scroll ended');
    });
    
    $('#scrollableDiv').scroll(scrollEnded);
    

    Demo

    【讨论】:

    • @马特。这正是我想要的方式。完美的。谢谢。
    【解决方案3】:

    您是否尝试过将 scrollEnded() 放在 bodyScroll() 之上?

    function scrollEnded(){
        console.log('scrollEnded. Now do something astounding.');
    };
    function bodyScroll() {
        console.log('scrolling.');
    
        if (scrollTimer != -1)
            clearTimeout(scrollTimer);
    
        scrollTimer = window.setTimeout('scrollEnded()', 500);
    
    };
    

    【讨论】:

      【解决方案4】:

      抱歉,我完全忽略了函数在闭包中的事实,因此在我之前的回复中该页面不可用。您可以通过以下方式使其工作:

      window.scrollEnded = function () { console.log('scrollEnded. No do something astounding'); }
      

      后跟一个

      window.setTimeout(window.scrollEnded, 500);
      

      这应该删除字符串的 eval,并将其放在全局范围内以供使用。在命名空间污染方面还有其他一些奇怪的地方,但目前我正在尝试稍微简单一些并帮助您实现它。

      【讨论】:

      • 避免在 setTimeout 中使用字符串,这使用 eval 被认为是不好的做法。而是使用匿名函数,例如:scrollTimer = setTimeout(function(){ scrollEnded(); }, 500);
      • 我试过了,它有效……为什么是“-1”?这是在编辑之前的解决方案吗?
      • 初始设置在引号中滚动结束,这会强制执行您通常希望远离的 eval 调用。真的只是一个试图快速回答的神器。
      猜你喜欢
      • 2013-09-12
      • 1970-01-01
      • 2012-02-08
      • 2022-11-29
      • 1970-01-01
      • 2016-11-19
      • 2016-04-08
      • 2022-10-06
      • 2012-10-30
      相关资源
      最近更新 更多