jQuery resize(), scroll(): good practice to use variables?

后端 未结 1 1512
隐瞒了意图╮
隐瞒了意图╮ 2021-01-21 01:05

So my website is experiencing lag when scrolling. I just wanted to ask if it\'s a good practice to initialize the jQuery objects that you need in $(window).scroll(functio

1条回答
  •  盖世英雄少女心
    2021-01-21 02:01

    In general you should avoid doing anything inside a callback that was fired by the scroll event because the callback will be executed for every pixel that the window is scrolled. However, depending on the application that you're building, some things simply cannot be avoided inside that callback.

    Doing a lot of "expensive" manipulations or queries inside the scroll callback can totally freeze the browser and will make your application unusable, so you have to be very careful and performance cautious.

    Here are some examples of good practices.

    A general example:

    Live example: 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();
    


    Sometimes you will need to do "expensive" DOM manipulations, queries, or even Ajax requests inside the scroll's callback function. For example imagine building an application that implements a pattern known as infinite loading. In this application when the user has reached close to the bottom of the page by scrolling quickly or slowly, you will need to do the following:

    1. Check if the user has scrolled to the bottom.
    2. Check if there are more resources to load.
    3. Load the resources.
    4. Append the new resources to the DOM.

    You definitely wouldn't want to execute all the steps above on every scrolled pixel. A very good practice for this situation is to delay the steps above. An example might look like this:

    Delayed execution:

    Live example: 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();
    


    The same principles would apply for the resize event too.

    0 讨论(0)
提交回复
热议问题