【问题标题】:window scroll : avoid multiple api hits based on scroll height窗口滚动:根据滚动高度避免多次 api 命中
【发布时间】:2016-06-01 15:01:42
【问题描述】:

我从 api 中获取数据,点击窗口滚动,即当用户在页面上达到 95% 时。问题是多个 api 命中被触发。

我假设这是由于 js 调用的异步特性,并且每次用户向下滚动时都会多次调用窗口滚动。

我确实放了一个变量“taskFired”来检查并仅在 API 命中逻辑尚未执行时才允许它。但是当用户向下滚动时,我得到 4-5 次 api 命中而不是 1 次。我无法找出原因。

代码如下:

//变量来检查我们是否已经点击了api或者现在已经达到了95%。默认为false。

var taskFired = false;

//滚动事件

$(window).scroll(function (evt) {
            if (!taskFired) { //allow to check and hit api if taskFired is false
                $.when(_self.scrollApiHit()).then(function () {
                    taskFired = false; //reset variable when api hit done
                });
            }                
        });

_self.scrollApiHit = function () {               
                var wintop = $(window).scrollTop(), docheight = $(document).height(), winheight = $(window).height();
                var scrolltrigger = 0.95;    

                if ((wintop / (docheight - winheight)) > scrolltrigger) {
                    taskFired = true;
                    //API HIT
                }
            };

我什至尝试设置 setTimeout,但即使这样也不起作用:

setTimeout(function () {
                    if (!taskFired) {
                        $.when(_self.scrollApiHit()).then(function () {
                            taskFired = false;
                        });
                    }
                },1000);

【问题讨论】:

    标签: jquery scroll infinite-scroll


    【解决方案1】:

    正如$.when 文档所述,

    如果单个参数传递给 jQuery.when() 并且它不是 Deferred 或 Promise,它将被视为已解决的 Deferred,并且任何附加的 doneCallbacks 都将立即执行。

    您必须确保 _self.scrollApiHit 确实返回了一个承诺,否则,taskFired 将立即设置回 false。你的函数_self.scrollApiHit 似乎不是一个承诺。

    你可以试试这样的:

    $(window).scroll(function (evt) {
            if (!taskFired) {               
                var wintop = $(window).scrollTop(), docheight = $(document).height(), winheight = $(window).height();
                var scrolltrigger = 0.95;    
    
                if ((wintop / (docheight - winheight)) > scrolltrigger) {
                    taskFired = true;
                    $.when($.ajax("API HIT HERE")).then(function () {
                        taskFired = false; //reset variable when api hit done
                    });
                }
            }                
        });
    

    【讨论】:

    • 你不认为这与放置'taskFired = false;'相同吗?在ajax成功失败回调中?
    • 是的,应该是一样的。我只是复制了 Promise 结构,因为你一直在使用它。
    【解决方案2】:

    在阅读了有关 when 和 deferred promise 的更多信息后,我尝试在 ajax 成功调用中重置 taskFired。

    这就是我所做的,它对我有用。

    $(window).scroll(function (evt) {
                    if (!taskFired) { //allow to check and hit api if taskFired is false
                        _self.scrollApiHit();
                    }                
                });
    
    _self.scrollApiHit = function () {               
                    var wintop = $(window).scrollTop(), docheight = $(document).height(), winheight = $(window).height();
                    var scrolltrigger = 0.95;    
    
                    if ((wintop / (docheight - winheight)) > scrolltrigger) {
                        taskFired = true;
                        //API HIT [on success set taskFired = false]
                    }
                };
    

    【讨论】:

      猜你喜欢
      • 2011-01-23
      • 2018-12-31
      • 1970-01-01
      • 2010-11-12
      • 2013-11-12
      • 2011-10-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多