我从窗口滚动上的 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]
}
};