在下面的代码中,我正在检查窗口是否正在滚动超过某个点,如果是,请更改元素以使用固定位置,以便它不会滚动到页面顶部.唯一的问题是,似乎是高度客户端内存密集型(并且实际上阻碍了滚动速度),因为在每个滚动像素我都在元素上反复更新样式属性.
在尝试更新之前检查attr是否已经存在会产生重大影响吗?是否有完全不同且更有效的实践来获得相同的结果?
$(window).scroll(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");
}
});
Run Code Online (Sandbox Code Playgroud)
当我输入此内容时,我注意到StackOverflow.com使用相同类型的功能,并在本页右侧使用黄色的"类似问题"和"帮助"菜单.我不知道他们是怎么做到的.
jfr*_*d00 57
您可以使用的一种技术是在滚动事件上设置计时器,并且仅在滚动位置在短时间内没有更改时才执行主要工作.我在具有相同问题的resize事件上使用该技术.您可以尝试使用哪种超时值正常工作.较短的时间更新,滚动时间较短,因此在滚动期间可能会更频繁地运行,较长的时间需要用户实际暂停所有运动一段有意义的时间.您将不得不尝试使用哪种超时值最适合您的目的,最好在相对较慢的计算机上进行测试,因为滚动延迟的问题最为明显.
以下是如何实现这一点的一般概念:
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");
}
}
Run Code Online (Sandbox Code Playgroud)
当滚动首次启动时,您也可以通过缓存某些选择器来加快滚动功能,这样就不必每次都重新计算.这是一个每次创建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);
Run Code Online (Sandbox Code Playgroud)
工作演示: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");
}
});
Run Code Online (Sandbox Code Playgroud)
Sam*_*uck 11
我发现这种方法更有效 $(window).scroll()
var userScrolled = false;
$(window).scroll(function() {
userScrolled = true;
});
setInterval(function() {
if (userScrolled) {
//Do stuff
userScrolled = false;
}
}, 50);
Run Code Online (Sandbox Code Playgroud)
查看John Resig关于此主题的帖子.
更高效的解决方案是设置一个更长的间隔,以检测您是否接近页面的底部或顶部.这样,你甚至不必使用$(window).scroll()