mouseleave event for document, with consideration for Chrome bug - javascript

I need to safely detect when the mouse leaves the window. I have jQuery included, so normally this would be fine:
$(document).on("mouseleave", function(event) {
doSomething();
});
However, there is a major bug in Chrome currently where this mouseleave function fires randomly when clicking in the element.
Normally, there's an easy work around for this:
$("#some-id").on("mouseleave", function(event) {
var e = event.originalEvent;
if (!e.relatedTarget || !e.toElement) {
// BUG in Chrome
return;
}
doSomething();
}
However, this doesn't work for document, or for any element when the mouse leaves the window, since in this case, e.relatedTarget and e.toElement are null exactly like when the bug occurs. So I'm trying to come up with something that will be able to safely determine when Chrome is acting up, and when the mouseleave event actually should fire.
Update: Just tried an approach with mouseout instead. The same chrome bug affects this event too, so no good. :/
UPDATE: this was apparently fixed, the Chrome issue was marked "fixed", and my tests show that the current version of Chrome no longer has the issue. :D

For now, this is the solution I came up with. Hopefully someday this major bug in Chrome gets enough attention to get a fix.
In the event that mouseleave occurs as a bug, it is usually almost immediately by the mouseenter event. So what I did here was just wait 1/10 of a second after the mouseleave event to make sure it's not a Chrome fluke.
var documentMouseLeaveTimeout = null;
$(document).on("mouseleave", function() {
documentMouseLeaveTimeout = setTimeout(function() {
doSomething();
}, 100);
});
$(document).on("mouseenter", function() {
clearTimeout(documentMouseLeaveTimeout);
});
Still hoping there's a better answer.
UPDATE: this was apparently fixed, the Chrome issue was marked "fixed", and my tests show that the current version of Chrome no longer has the issue. :D

Related

IE raises blur on focus in textbox

First of all, this is my first question here, sorry if it is not asked properly.
I have a bug in a web app we developed in the office. The app is nearly done but In IE < 9 it happens that a text-box which has focus and blur events attached with jQuery raises the blur event as soon as you click on it.
You can see this in this picture (just clicked in the text-box):
https://www.dropbox.com/s/yn10xfrfxsr38bq/screen.PNG
$('#divVolee [type="text"]')
has no focusin or focus events attached.
The URL to the application:
http://86.126.255.70:2213/Anoxa/
If you want you can enter using the "Demarrer" button.
I do not ask anybody to write code for me or anything like that, I just don't know after days of searching in the code and on the net what could cause that.
I tried focusin, focus, focusout, blur, attaching directly or using delegates, the same thing. As soon as I click in the input field it raises the blur / focusout event.
Thank you for your help.
I found it. I started to comment everything out until I found the culprit:
function resizeAccordion() {
var active = $('#divAccordion').accordion('option', 'active');
$('#divAccordion').accordion('destroy').accordion({ heightStyle: "fill", active: active });
}
var resizeId;
$(window).resize(function () {
clearTimeout(resizeId);
resizeId = setTimeout(resizeAccordion, 600);
});
This code was supposed to re-size and re arrange the accordion in the page if the user re-sized the browser. Somehow in IE<9 it got triggered without reason and this caused the blur event to be triggered.
After so many hours. Maybe it is may thinking or code that was wrong, but i still hate IE for it.
I cannot reproduce this bug (using IE8 mode under IE9). But a simple workaround could be: (even quite weird)
$('#divVolee [type="text"]').focus(function(){
//>>code for FOCUS here<<
$(this).blur(blurcallback);
});
function blurcallback()
{
//>>code for BLUR here<<
$(this).off('blur');
}

jqGrid: Column resize triggers click event

First of all, these are the versions I am currently using:
jqGrid 4.3.2 with the fix for Chrome (posted by "Oleg" in jqGrid does not render correctly in Chrome/Chrome Frame). For some reason 4.3.2 and 4.4.0 did not solve the width issue for me as described in the post. The issue just popped up in IE in addition to Chrome.
jQuery 1.7.2
jQuery UI 1.8.9
The problem I am having is that when I try to resize one of the columns in the grid by dragging the mouse it seems to trigger the click event on the header to the left of the separator when I let go of the mouse button. This event then triggers reordering of the rows, so it is not very nice.
It only happens in IE (9), it works fine in Firefox and Chrome.
I think this is very strange, since I have not found anyone else who describes the same issue with jqgrid, and I don't think I do any "hacks" that would potentially give this behaviour.
Hope someone could point me in a direction here.
I did not find exactly what the root cause for my problem was, but managed to solved it by suspending the click handler in jqgrid for 10 milliseconds after the mouseup event on the column resize action. The click handler allready had a check for a variable called ts.p.disableClick, so I figured I might as well use this one. The only thing I needed to change was from this:
$(document).mouseup(function () {
if (grid.resizing) { grid.dragEnd(); return false;}
return true;
});
, to this:
$(document).mouseup(function () {
if (grid.resizing) {
// Disabling the click handler for 10 millisec.
ts.p.disableClick = true;
setTimeout(function() {
ts.p.disableClick = false;
}, 10);
grid.dragEnd(); return false;
}
return true;
});
You may call this a hack, but suspending the click handler for just 10 ms should not affect the user in any way, so I think it should be safe.
Hopefully this could be helpful if someone encounters a similar problem.

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.

$(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) { ... });

window.parent jQuery selector not working in IE8

This code below works fine
$('html').bind('mousewheel', function(event, delta) {
window.parent.scrollBy(-120 * delta,0);
return false;
});
but this one doesn't, can anyone tell me why. I'd love to know.
$(window.parent).bind('mousewheel', function(event, delta) {
window.parent.scrollBy(-120 * delta,0);
return false;
});
I'd like to clarify that the window selector doesn't work in this case either.
The problem may be that jQuery's event handler wrapper must use window.event to retrieve the current event in IE. If you set a handler from window A on an event in window B, the script in window A will be looking at window A's window.event, whilst the event is actually occurring on window B.
But there may be more issues than that, too. Cross-window/frame scripting is fraught with difficulties and jQuery is not particularly designed to work around them. To make jQuery work properly cross-frame you will generally need an instance of jQuery in both windows, and you should only use the corresponding instance of jQuery ($) to interact with each window.
eta re comment:
OK, having looked into mousewheel further, I don't know how your code can be working in Firefox (it certainly doesn't for me). Firefox doesn't support mousewheel events at all; instead it supports DOMMouseScroll events. Also for the other browsers that support mousewheel, it should be bound to a DOM Node rather than the window. So I guess what you're looking for is:
if ('MouseScrollEvent' in window) {
$(document).bind('DOMMouseScroll', function(event) {
return scroll(event.detail*-40);
});
} else {
$(document).bind('mousewheel', function(event) {
return scroll(event.wheelDelta);
});
}
function scroll(d) {
window.scrollBy(-d, 0);
return false;
};
(However in WebKit this will stop scrolling when the mouse moves out of the horizontal area corresponding to the viewport width. You may prefer to bind the events to the wider element like the div, if it fills the browser.)

Categories