窗口滚动 :避免根据滚动高度多次点击 API



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

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

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

代码如下所示:

变量来检查我们是否已经达到了 API 或现在已达到 95%。默认情况下,它是假的。

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);

正如$.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
                });
            }
        }                
    });

在阅读了更多关于何时和延迟承诺的信息后,我尝试重置任务在 ajax 成功调用中触发。

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

$(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]
                }
            };

最新更新