How can I prevent onscroll function to trigger during resize? - javascript

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!

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
}

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.

Related

Window.addEventListener For Scroll is Not Firing

I've added an event listener to wait for the user to scroll, there is a lodash debounce function to keep it from firing too often, and it affects the state of a nav widget on the page from inactive to active.
function findActiveItemOnScroll() {
const fromTop = window.pageYOffset;
listLinks.forEach(listLink => {
(...Code)
});
(...Code)
}
const debounceScrollEvent = debounce(findActiveItemOnScroll, 10);
window.addEventListener('scroll', debounceScrollEvent);
However, it's just not firing! I've checked for any overflow or 100% height on the body/html. I've checked window.pageYOffset and it is scrolling properly. Are there any other selectors or JS functionality that can affect a scroll event that I'm missing?
So I ended up resolving the issue. The problem was that the function was getting held up higher up in the chain and the event listener was never actually getting set in the first place, ergo, never getting fired.

Weird behaviour in jscrollpane with scroll event?

api.scrollToY function is running recursively in scroll event only , is there any way to stop it?
$('.scroll-pane').bind('scroll',function (e) {
api.scrollToY(100)
return false;
});
I don't understand, but if you need to listen an event like scroll or resize (that fires tons of times) you can use a debouncer for your function. Underscore library have one very useful. See more:
http://davidwalsh.name/javascript-debounce-function
You can modify easy to change resize to scroll
var myEfficientFn = debounce(function() {
// All the taxing stuff you do
}, 250);
window.addEventListener('scroll', myEfficientFn);

Why does my JavaScript onresize fire twice?

I have a fiddle here:
http://jsfiddle.net/fJMe9/
window.onresize = function (e) {
console.log("Page resized");
};
And every time I resize the window I get two logs to the console
It's a well known bug (perhaps relating to event bubbling? I say well known, but that's other people who know it, not me :P ). Use a setTimeout to check the last time the window was resized to avoid this.
Try:
window.onresize = function (e) {
console.log(e);
};
you'll see the event fires every time you drag the browser window
Depends on implementation: maybe 2 times, the first for tell you the window is being resized and the second for windows finished resizing.

Remove window "resize" listener

This question relates closely to the stack overflow question "window.resize event firing in Internet Explorer".
The Issue:
I am attempting to fix a resizing issue in Internet Explorer 8. Currently, the resize function gets called repeatedly causing IE to essentially lock up - the user can no longer use buttons that call Javascript actions.
Previous Attempt(s):
var resizeTimeout;
var resizeHandler = function() {
clearTimeout(resizeTimeout);
//$(window).unbind('resize', resizeHandler);
//window.removeEventListener('resize');
window.removeEventListener('resize', resizeHandler, false);
scrollHandler();
setTimeout("$(window).resize(resizeHandler);", 100);
return true;
}
//$(window).resize(resizeHandler);
window.addEventListener('resize', resizeHandler, false);
Problems: It appears that window cannot implement addEventListener or removeEventListener and unbinding jQuery doesn't stop IE from continuing to freak out. It works fine in all other browsers.
Desired Behavior: The goal here is really to get IE to stop repetitively executing code so other functions like onclick events work.
Does anyone know how I can remove the resize event after it's been added or simply make IE stop being retarded. (<-- Extra points if you can make IE not be retarded.)
Resolution: Inside of the scrollHandler function a variable was not declared using the var prefix. Adding var made all the evil fairies go away.
I think you're going about this the wrong way. What you should be doing is using that timeout to block the invocation of "scrollHandler()" until the window resizing activity has paused for a little while (like the 100ms delay you're using).
var resizeTimeout;
function resizeHandler() {
cancelTimeout(resizeTimeout);
resizeTimeout = setTimeout(scrollHandler, 100);
}
$(window).resize(resizeHandler);
Trying to do DOM updates (which I assume to be what goes on inside "scrollHandler") in a "resize" handler is really not a good idea in any browser. By doing that, you won't need to get rid of the "resize" handler at all.
edit — OK now I see that that's effectively what you were trying to do. I still think it's a lot simpler this way.

Firefox scrollTop problem

I have a problem with Firefox scrollTop value and onscroll event. This works great in IE, Safari and Chrome but Firefox seems to lag.
I tried to update some background position with the onscroll event, but when I take the handle and drag it up and down quickly, Firefox stops updating the scrollTop value and it causes some lag in my app.
You can try this code and look in the Firefox console when dragging the handle and you will see the values something stops the updating :
function SaveScrollLocation () {
console.log(document.documentElement.scrollTop);
}
window.onscroll=SaveScrollLocation ;
Any idea how to make Firefox respond more quickly?
There are two ways to handle this - throttle (execute the function with a set interval) and debounce (execute the function after the specified time has passed since the last call). You'll probably want to use throttling in your situation.
A simplified solution may look something like this (Updated: see it at http://jsfiddle.net/yVVNU/1/):
window.onscroll=catchScroll;
var timeOutId = 0;
var jitterBuffer = 200;
function catchScroll()
{
if (timeOutId) clearTimeout (timeOutId);
timeOutId = setTimeout(function(){SaveScrollLocation()}, jitterBuffer);
}
function SaveScrollLocation () {
console.log(document.documentElement.scrollTop);
alert('scrolled');
}
You can also use this jQuery plugin: http://benalman.com/projects/jquery-throttle-debounce-plugin/
$(window).scrollTop() worked for me
Wouldn't the behavior of dragging the window up and down quickly be considered abnormal?
In my view, I wouldn't want to be saving the state if the user is doing that. I'd rather wait until the window has been in the same spot for at least 250ms before recording it's position. The minor variances in position while the user is slamming the scrollbar up and down are probably not very important to the user, know what I mean?
With a little setTimeout magic, couldn't you sidestep this issue AND make your script a little lighter on the browser UI by not firing the SaveScrollLocation until it clear the scroll location is WORTH saving?
Firefox does not (or did not used to) fire the onscroll event as frequently as the other browsers. see here
Interestingly the scrollTop does update at the correct frequency so you can probably use another event such as mousemove. What i did was something like this :
on first scroll event, start listening to mouse move events - update whatever it is you want to based on the scrollTop which does update correctly. After a short timeout has elapsed after an onscroll, stop listening for mouse move events.
var last = +new Date;
function SaveScrollLocation () {
var now = +new Date;
if (now - last > 50) {
// ...
last = now;
}
}
window.onscroll = SaveScrollLocation ;

Categories