0

I have a problem when creating plugin. The problem came up when setting new value for variable width.

width variable need to calculate again, if user resizes his browser. If i attach resize event inside loop, it will make trouble performance. I came up with the idea to create closure function for wrapping all CODE. So, when the user resize his browser, i call this function again.

JS :

var self         = this,
    onScrollbarY = function() {
        self.each(function() {  // loop it
            var el           = $(this),
                elLog        = el.find(".scrollbarYLog"),
                width        = $(window).innerWidth(),    // this value will change based on users browser width
                onMouseOver  = function() {
                    elLog.html(width);
                };
            elLog.on("mouseover", onMouseOver);
        });
    };
onScrollbarY(); // call it immediatly

$(window).on("resize", onScrollbarY); // if users resize its browser, call it again for getting new browser width

Is this the correct way to accompolished it? or there are other option which more efficient rather than attach all code again?

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
Ching Ching
  • 1,029
  • 4
  • 19
  • 33
  • There is a technique called `debouncing.` A quick SO search brought up this link: http://stackoverflow.com/questions/5489946/jquery-how-to-wait-for-the-end-of-resize-event-and-only-then-perform-an-ac, but you might want to search for others. -- Better link to a generic debouncer: http://stackoverflow.com/questions/4298612/jquery-how-to-call-resize-event-only-once-its-finished-resizing – Jeremy J Starcher May 15 '16 at 10:17

1 Answers1

1

The reason why you had a performance problem in the first place is that every time you called .on('resize', ...), you registered a function that runs on that event. So after 5 resize events, you had 5 functions that were called every time, which is what caused the slow-down.

There are two ways to approach this problem:

  1. only attach one handler to that event (what you ended up doing); or
  2. use the .one('resize', ...) event handler to register a function that will only be triggered on the first next resize event.

Use case #1 is what the majority of developers use and recommend. You create a function (like your onScrollbarY) and you register that function using .on() to be called each time the resize event happens from the moment you register it.

The case #2 is very rare and you probably don't want to use .one() unless you only want to handle the first occurence of that event, and none after that. If you wanted to handle more than one, you would have to call .one() again after the event happens to tell it to listen for that event again.

EDIT: You can simplify your code to the following:

var $window  = $(window),
    width    = $window.innerWidth(), // we know the initial width
    $elLog   = $(".scrollbarYLog"),  // we find the scrollbar element
    onResize = function() {
      width = $window.innerWidth();
    },
    onMouseOver = function() {
      $elLog.html(width);
    };

// register the resize function with the "resize" event
$window.on("resize", onResize);
// register the mouseover function with the "mouseover" event on the scrollbar
$elLog.on("mouseover", onMouseOver);

// there is no need to call onResize(), as we've already set the width variable
Klemen Slavič
  • 19,661
  • 3
  • 34
  • 43
  • thanks Klemen for answering! your explanation is very cool. i'm just wondering, if i call `onScrollbarY` 5 times or more. will `elLog.on("mouseover", onMouseOver);` also attach 5 times, or it will replace from current event? i'm just worry about the perfomance when its resize too much. – Ching Ching May 15 '16 at 11:01
  • You shouldn't be calling `.on()` inside a loop, since each time `onScrolbarY` is called, it would add another function to execute during `mouseover`. You should register `on('mouseover')` outside of `onScrollbarY`. – Klemen Slavič May 15 '16 at 11:04
  • something like this? https://jsfiddle.net/njm50ero/ please correct it if i'm wrong – Ching Ching May 15 '16 at 11:08