Remove window "resize" listener - javascript

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.

Related

'transitionend' event does not fire consistently

The following code works inconsistently with Chrome but also Firefox (with 'transitionend'). The function slogan_fade_next is just console.log('end');. I always get the classname applied to the first span element but anything after that is hit-and-miss when I click the refresh button, reload, or anything else.
The class of slogan-fadein applied to slogan[] changes the opacity of the element from zero to one but the callback function fade_setup isn't called consistently.
function fade_setup(){
var el = document.getElementsByClassName('slogan')[0];
el = el.getElementsByTagName('span');
for(var i=0;el[i];i++){
el[i].addEventListener('webkitTransitionEnd',slogan_fade_next,false);
}
el[0].className='slogan-fadein';
}
document.addEventListener('DOMContentLoaded', fade_setup);
instead of
document.addEventListener('DOMContentLoaded', fade_setup);
can you use
document.addEventListener('load', fade_setup)
With your current implementation, the JavaScript may be running before the browser has finished applying styles and, therefore, before any transitions are defined.
The problem is caused by a timing issue with applying the styles and anything else as mentioned by Stephen. The problem is, things aren't settled by the time I try to fire the first fade in so I triggered that with window.onload=slogan_fade_next;. Everything has settled in by the time my first element has done its thing.
I've given absolutely no more thought to this other than "it works" and I'm sure I'll come up with a better way to do this.

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.

$(window).mouseup handler in a Chrome extension is breaking Flash

I'm working on a Google Chrome extension that monitors mouse events. For some reason the following javascript code in the extension's content script is causing embedded Flash content to break:
$(window).mouseup(function() {
// do benign stuff
});
If you mousedown inside a Flash element, it never registers the mouseup and it appears as though you're still holding your mouse button down even though you've let go. At first I thought it was some kind of event bubbling issue, that this method was swallowing the event, so I tried returning true (and false for that matter) but it didn't seem to have any effect. Any ideas?
Well, no response from the peanut gallery after a few days, but I figured it out on my lonesome:
// Bad
$(window).mouseup(function() { ... });
// Good
window.addEventListener("mouseup", function(event) { ... });

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 ;

`return false` in an event handler attached by addEventListener or element.on*

Right let’s get this out the way first. Yes, I want to hide the context menu. No, I’m not trying to prevent someone lifting content off my page. Its intended use is input for an in-browser game and it will be limited to a specific area on the webpage.
Moving from the ideological to the technical...
var mouse_input = function (evt) {
// ...
return false;
}
document.onmousedown = mouse_input; // successful at preventing the menu.
document.addEventListener('mousedown', mouse_input, true); // unsuccessful
Could someone explain to me why the addEventListener version is unable to stop the context menu from firing? The only difference I was able to see in Safari's Web Inspector was that document.onmousedown had a isAttribute value that was true whilst the addEventListener version had the same value as false.
So my unfruitful search suddenly became fruitful.
var mouse_input = function (evt) {
evt.preventDefault();
}
document.addEventListener('contextmenu', mouse_input, false);
Works for Safari, Firefox, Opera. preventDefault() stops the usual actions from happening. I had to change the event that was listened for to accommodate for Safari and it is more logical anyway. Further information: functions that implement EventListener shouldn’t return values so return false had no effect.
To explain the difference .. element.onmousedown = somefunction; is an absolute assignment; you are replacing the event handler on the element. element.addEventListener(...) is, as the name implies, adding a handler in addition to any handler(s) already attached for the event.

Categories