【问题标题】:jQuery resize(), scroll(): good practice to use variables?jQuery resize(), scroll():使用变量的好习惯?
【发布时间】:2015-02-16 10:02:55
【问题描述】:

所以我的网站在滚动时遇到了延迟。我只是想问一下在$(window).scroll(function () {}中初始化你需要的jQuery对象是否是一个好习惯?

例如:

$(window).scroll(function () {
  $thisContainer = $('.section #container');

  // 10 more initializations...
  $thisContainer.css(); // something like that...
}

我觉得这不是一个好主意,因为每次用户滚动时都会经常调用此函数。当它被调用时,这些变量将被重新初始化。结果会浪费大量的内存和时间。

谢谢!

【问题讨论】:

  • .scroll之外进行操作
  • @Vega 如果我每次都使用$() 会影响速度吗?这肯定会影响代码的可读性。
  • @ 使用$() 将调用一个jQuery函数并根据内部的选择器对其进行初始化..所以每次滚动时就像一遍又一遍地调用函数。
  • @Vega 我明白了,感谢您的快速回复。
  • 你想在那个滚动里面初始化什么?看来一定有更好的方法来初始化东西。

标签: javascript jquery


【解决方案1】:

一般来说,您应该避免在由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 请求。例如,想象构建一个实现称为无限加载的模式的应用程序。在此应用程序中,当用户通过快速或慢速滚动接近页面底部时,您需要执行以下操作:

  1. 检查用户是否滚动到底部。
  2. 检查是否有更多资源要加载。
  3. 加载资源。
  4. 将新资源附加到 DOM。

您绝对不想对每个滚动像素执行上述所有步骤。对于这种情况,一个非常好的做法是延迟上述步骤。一个示例可能如下所示:

延迟执行:

现场示例: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 事件。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-04-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多