您可以使用的一种技术是在滚动事件上设置一个计时器,并且仅在滚动位置在短时间内没有改变时才执行主要工作。我在具有相同问题的调整大小事件上使用该技术。您可以试验一下似乎可以正常工作的超时值。更短的时间更新与更短的滚动暂停,因此可能在滚动期间更频繁地运行,更长的时间需要用户实际暂停所有运动有意义的时间。您将不得不试验哪种超时值最适合您的目的,最好在相对较慢的计算机上进行测试,因为这是滚动延迟问题最明显的地方。
以下是如何实现的总体思路:
var scrollTimer = null;
$(window).scroll(function () {
if (scrollTimer) {
clearTimeout(scrollTimer); // clear any previous pending timer
}
scrollTimer = setTimeout(handleScroll, 500); // set new timer
});
function handleScroll() {
scrollTimer = null;
var headerBottom = 165;
var fcHeight = $("#pnlMainNavContainer").height();
var ScrollTop = $(window).scrollTop();
if (ScrollTop > headerBottom) {
$("#HeaderContentBuffer").attr("style", "margin-top:" + (fcHeight) + "px;");
$("#AddFieldsContainer").attr("style", "position:fixed;width:320px;top:70px;left:41px;");
} else {
$("#HeaderContentBuffer").attr("style", "margin-top: 0px;");
$("#AddFieldsContainer").removeAttr("style");
}
}
您还可以通过在第一次滚动开始时缓存一些选择器来加快滚动功能,这样就不必每次都重新计算它们。这是每次创建 jQuery 对象的额外开销可能对您没有帮助的地方。
这是一个为您处理滚动计时器的 jQuery 附加方法:
(function($) {
var uniqueCntr = 0;
$.fn.scrolled = function (waitTime, fn) {
if (typeof waitTime === "function") {
fn = waitTime;
waitTime = 500;
}
var tag = "scrollTimer" + uniqueCntr++;
this.scroll(function () {
var self = $(this);
var timer = self.data(tag);
if (timer) {
clearTimeout(timer);
}
timer = setTimeout(function () {
self.removeData(tag);
fn.call(self[0]);
}, waitTime);
self.data(tag, timer);
});
}
})(jQuery);
工作演示:http://jsfiddle.net/jfriend00/KHeZY/
然后您的代码将像这样实现:
$(window).scrolled(function() {
var headerBottom = 165;
var fcHeight = $("#pnlMainNavContainer").height();
var ScrollTop = $(window).scrollTop();
if (ScrollTop > headerBottom) {
$("#HeaderContentBuffer").attr("style", "margin-top:" + (fcHeight) + "px;");
$("#AddFieldsContainer").attr("style", "position:fixed;width:320px;top:70px;left:41px;");
} else {
$("#HeaderContentBuffer").attr("style", "margin-top: 0px;");
$("#AddFieldsContainer").removeAttr("style");
}
});