How to detect when the mouse leaves the browser’s viewport in javascript

Posted on Tuesday September 29th, 2009 by Matt
1 Star2 Stars3 Stars4 Stars5 Stars (No Ratings Yet)
Loading ... Loading ...

Javascript is a very useful language for many things nowadays.
Unfortunately, each browser implements it in a different way, and of course they don’t offer the same way of handling events !

Let’s take an example : you’ve just made a div that you can drag at will with the mouse. We click, the dragging begins… we let go of the mouse button, the dragging stops. But here’s the thing : if we let go of the mouse button while outside the browser’s viewport, no event is triggered, and we keep on dragging our div indefinitely !

The best way to prevent that is to stop the dragging as soon as we leave the browser’s viewport. But : javascript doesn’t trigger any event in that case. One has to cheat…

We begin by saying that if we stop hovering the dragged object, we’ll stop the dragging…
And we soon realise it’s not cool at all ! Indeed, the mouse will nearly always go faster that the div and the dragging will stop instantly, except if we move in slow motion.

To prevent that, one can check toward which element the mouse left the div, and only stop the dragging if that element is not within the html tag.
Easy… in theory. But all browsers don’t use the same attributes for the event, and of course IE will be causing trouble !

Without any further introduction, here is a bit of jQuery (“code less do more”) that will help you a lot to solve that issue :

$('div#dragged').bind('mouseleave.dragged',function(e) {
	var ev = e || window.event;
	if(ev.relatedTarget){
		if(ev.relatedTarget == $('html').get(0)){
			stopDrag();
		}
	} else {
	// IE
		if(!ev.toElement){
			stopDrag();
		} else if(ev.toElement.tagName == "HTML"){
			stopDrag();
		}
	}
})

Now, the explanations :

$('div#dragged').bind('mouseleave.dragged',function(e) {

We associate a function to the ‘mouseleave’ event on the draggable div.
Please note that jQuery allows us to associate a name to that function (here: ‘.dragged’), which is very useful to then handle the events by name, specially in the case where several events of the same type are associated with this object.

	var ev = e || window.event;

We get the triggered event. Firefox and the standard compliant browsers will have it as a parameter of the function (here : ‘e’), for Internet Explorer we’ll have to fetch it from the window.event.
the double pipe (‘||’) allows us to give to the variable ‘ev’ the value of ‘e’ if it exists, and the value of ‘window.event’ if that’s not the case.

	if(ev.relatedTarget){
		if(ev.relatedTarget == $('html').get(0)){
			stopDrag();
		}

For the standard browsers, the event contains a ‘relatedTarget’ property.
If it exists, we are in the case of a standard browser, else we’re probably dealing with IE.

This property contains the ‘html’ element when we leave the browser’s viewport.
Here we’ll use a jQuery syntax to compare the content of that property to the html content (‘get(0)’ on the jQuery object) of the ‘html’ tag. If they’re identical, we can stop the dragging.

	} else {
	// IE

If the ‘relatedTarget’ property doesn’t exist, we’re in the case of IE. Two case are then to be taken care of :

		if(!ev.toElement){
			stopDrag();

For some versions of IE, the ‘toElement’ property of the event is undefined. This is enough information to stop the dragging.

		} else if(ev.toElement.tagName == "HTML"){
			stopDrag();
		}
	}
})

For some other versions of IE, the ‘toElement’ property exists. We’ll then have to check that the ‘tagName’ property of the ‘toElement’ is indeed ‘HTML’. If that’s the case, we’ll stop the dragging.

Here it is, I hope this short explanation may help you out, it’s not always easy to find on the internet the needed resources to do that thing that seems so basic !

One Comment to 'How to detect when the mouse leaves the browser’s viewport in javascript'

  1. Twitted by formeolibre said :

    [...] This post was Twitted by formeolibre [...]

Leave a Comment

Top of page