所以滚动时我的网站遇到了延迟。我只是想问一下,在$(window).scroll(function () {}
中初始化所需的jQuery对象是否是一个好习惯?
例如:
$(window).scroll(function () {
$thisContainer = $('.section #container');
// 10 more initializations...
$thisContainer.css(); // something like that...
}
我觉得这不是一个好主意,因为每次用户滚动时都会经常调用此函数。当它被调用时,这些变量将被重新初始化。结果会浪费大量的记忆和时间。
谢谢!
答案 0 :(得分:5)
通常,您应该避免在scroll
事件触发的回调中执行任何操作,因为将对窗口滚动的每个像素执行回调。但是,根据您正在构建的应用程序,在回调中有些事情是无法避免的。
做了很多"昂贵的"滚动回调中的操作或查询可以完全冻结浏览器并使您的应用程序无法使用,因此您必须非常小心并且性能谨慎。
以下是一些良好做法的例子。
实例:http://jsfiddle.net/tfjyf0a3/
// Since we can get away with querying the elements outside of the callback
// our application will be a lot snappier because we're doing less work for
// every scrolled pixel. Always query DOM elements outside if possible.
var $output = $('#output');
var $window = $(window);
// This function is executed for every scrolled pixel, so we need to
// avoid doing "expensive" queries or changing the DOM in here too.
function changeFontSize(scrollNumber) {
// Setting the fontSize here is unavoidable because our application needs it.
$output.css('fontSize', scrollNumber <= 50 ? 18 : Math.floor(scrollNumber/10));
}
$window.on('scroll', function() {
// Since `$(this)` here would be the window object, it's better to
// just use the previous reference named `$window`.
// Querying the scrolled position here is unavoidable because our
// application needs it.
var currentScroll = $window.scrollTop();
// Saving a reference of the `scrollTop()` value is better when
// we need to re-use its value.
$output.html(currentScroll + 'px');
// We have to be cautious inside this function as well.
changeFontSize(currentScroll);
});
// This is a good practice when you need to guarantee the execution of the function
// when there isn't enough content in the body to cause a scrollbar in the Browser.
//
// The 'scroll' event will fire only when there is a scrollbar in the Browser.
$window.scroll();
有时候你需要付出昂贵的代价。滚动的回调函数中的DOM操作,查询甚至Ajax请求。例如,想象一下构建一个实现称为无限加载模式的应用程序。在此应用程序中,当用户通过快速或慢速滚动到达页面底部时,您需要执行以下操作:
您绝对不想在每个滚动像素上执行上述所有步骤。这种情况的一个很好的做法是推迟上述步骤。示例可能如下所示:
实例:http://jsfiddle.net/35qb1b88/
var $output = $('#output');
var $window = $(window);
var timer;
function changeFontSize(scrollNumber) {
$output.css('fontSize', scrollNumber <= 50 ? 18 : Math.floor(scrollNumber/10));
// ...
// load resources
// append in DOM
// ...etc
}
function scrollHandler() {
var currentScroll = $window.scrollTop();
$output.html(currentScroll + 'px');
changeFontSize(currentScroll);
}
// This callback will be executed for every pixel but it will
// do nothing if we're scrolling too fast because we're clearing
// the timeout. Only when scrolling has stopped and at least 100
// milliseconds have passed will the `scrollHandler` function run.
$window.on('scroll', function() {
timer && window.clearTimeout(timer);
timer = window.setTimeout(scrollHandler, 100);
});
$window.scroll();
同样的原则也适用于resize
事件。