window 滚动:避免基于滚动高度的多次 api 命中
window scroll : avoid multiple api hits based on scroll height
我正在从 api 命中 window 滚动获取数据,即当用户在页面上达到 95% 时。问题是多次 api 命中被解雇。
我假设这是由于 js 调用的异步性质和 window 每次用户向下滚动时滚动被调用多次。
我确实放了一个变量 'taskFired' 来检查并允许 api 仅当它尚未执行时才命中逻辑。但是当用户向下滚动时,我仍然得到 4-5 api 次点击而不是 1 次。我无法找出原因。
代码如下:
//检查我们是否已经命中 api 或已达到 95% 正确度的变量 now.By 默认为 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);
如 $.when
文档所述,
If a single argument is passed to jQuery.when() and it is not a Deferred or a Promise, it will be treated as a resolved Deferred and any doneCallbacks attached will be executed immediately.
您必须确保 _self.scrollApiHit
实际上是 returns 一个承诺,否则 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 成功调用中重置 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]
}
};
我正在从 api 命中 window 滚动获取数据,即当用户在页面上达到 95% 时。问题是多次 api 命中被解雇。
我假设这是由于 js 调用的异步性质和 window 每次用户向下滚动时滚动被调用多次。
我确实放了一个变量 'taskFired' 来检查并允许 api 仅当它尚未执行时才命中逻辑。但是当用户向下滚动时,我仍然得到 4-5 api 次点击而不是 1 次。我无法找出原因。
代码如下:
//检查我们是否已经命中 api 或已达到 95% 正确度的变量 now.By 默认为 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);
如 $.when
文档所述,
If a single argument is passed to jQuery.when() and it is not a Deferred or a Promise, it will be treated as a resolved Deferred and any doneCallbacks attached will be executed immediately.
您必须确保 _self.scrollApiHit
实际上是 returns 一个承诺,否则 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 成功调用中重置 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]
}
};