4

I have two event handlers defined:

window.onresize = repositionElements;

scrollElement.onscroll = handleScrollBusiness;

Now, when I resize the window, I do not want my onscroll event to fire (which it ususally does during resizing). So I thought I temporarily set some isResizing variable to true and only set it back to false after a timeout. In the onscroll function I would then first of all check, if isResizing is false and only then proceed.

However, now during testing this, I realized that when I start to resize the window, it both fires a scroll and resize event, but it fires the onscroll event first, so my onresize has no chance to disable the scroll function, since it only gets fired after the scroll function has started to execute.

Is there any way around this? Can I globally change the order of these two events? If not, what other way would there to disable the onscroll event immediately once I start resizing?

I am looking for an answer in vanilla JavaScript. Also I am new to this, so if I have some logical flaws in my way to approach this, please let me know.

Thank you!

mdomino
  • 1,195
  • 1
  • 8
  • 22

2 Answers2

3

Since you haven't posted an example code of your problem, I'm not sure if what I'm about to write helps you or not.


You could try to defer the execution of onscroll handler by wrapping it's code inside a zero-length timeout, which effectively moves the execution of that piece of code to the end of current execution stack.

Here's an example:

window.onscroll = function () {
    setTimeout(function () {
        // your code here...
    }, 0);
}

window.onresize = function () {
    // your code here...
    // should be executed before onscroll handler
}
mdziekon
  • 3,531
  • 3
  • 22
  • 32
  • Works like a charm! Thank you. If others are in the same situation: It *did* cause my function not to work properly anymore, since I was passing a `this` which was overwritten by the setTimeout, but another answer [here](https://stackoverflow.com/questions/2130241/pass-correct-this-context-to-settimeout-callback) helped me, I just needed to save my `this` into another variable before calling `setTimeout` and then use that variable within the function and so it worked again. Thanks again, mdziekon! – mdomino Aug 11 '17 at 12:46
  • You could also use arrow functions to preserve ``this`` value. – mdziekon Aug 11 '17 at 12:47
  • As a newbie I have no idea what arrow function are, but I will make sure to read up about them. :) – mdomino Aug 11 '17 at 12:50
  • 1
    One of the reasons they were introduced in ES2015 was to remove the need to preserve ``this`` value. You can read more about them at MDN: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions – mdziekon Aug 11 '17 at 12:52
1

You can use RxJs Observable for this:

var resizeOb$ = Rx.Observable.fromEvent(window, 'resize');
var scrolOb$ = Rx.Observable.fromEvent(window, 'scroll')
              .takeUntil(resizeOb$);
scrolOb$.subscribe(function(event){

     /* handle scroll event here */
});
resizeOb$.subscribe(function(event){

     /* handle resize event here */
});

This will efficiently handle the situation for you.

asmmahmud
  • 4,844
  • 2
  • 40
  • 47