View Full Version : I still can't get my head round event bubbling ...
brothercake
03-22-2003, 07:20 PM
Say with this example:
<div id="test" onmouseout="mouseoutFunction(this)" style="padding:20px;background-color:pink">
<div style="padding:20px;background-color:yellow">
<a href="#" style="background-color:beige;">All your base are belongs to us</a>
</div>
</div>
<script type="text/javascript">
function mouseoutFunction(obj)
{
alert("mouseout");
}
</script>
</body>
</html>
I'm looking for a cross-browser method for making sure that the mouseout alert only happens when your mouse leaves the outer "test" DIV ?
boywonder
03-22-2003, 07:36 PM
Here is a good article: http://www.brainjar.com/dhtml/events/
hope that helps
Something like this should work. Instead of mouseoutFunction(this), use mouseoutFunction(event).
And now:
HTMLElement.prototype.contains = function(node) {
var range = document.createRange();
range.selectNode(this);
var response = range.intersectsNode(node);
range.detach();
return response;
}
function mouseoutFunction(evt) {
if (!document.getElementById("test").contains(evt.relatedTarget || evt.toElement)) {
// left test, do whatever
}
}
A more efficient contains method for kicks and giggles:
HTMLElement.prototype.contains = function(node) {
if (node == null)
return false;
if (node == this)
return true;
else
return this.contains(node.parentNode);
}
I think a simple recursive function like this is a little more efficient than a Range.... plus this is pure DOM1, while the previous method utilized a proprietary extension to the Range interface Mozilla threw in.
brothercake
03-22-2003, 09:07 PM
Okay ... well I can't say I fully understand that, but it's a working example to start with; I'm sure I'll grok it soon enough :) Thanks.
Well, relatedTarget is the W3C DOM2 property for whatever element the mouse is being moved into, and toElement is IE's. So basically I'm seeing if "test" contains the related target. If it does, one can make the assertion that the mouse is still inside "test". Else, the mouse is outside "test", and hence your concept of "mouseout" took place.
brothercake
03-23-2003, 12:49 AM
Aha :)
liorean
04-23-2004, 02:31 PM
I can see one problem with that, though: HTMLElement is defined as an interface in the DOM specs, not as a class or an object. That means that it might be present as a class or object (i.e. the way Gecko does it). It might also not be present as a class or object, or be an internal class or object that is not externally reachable (i.e. from the document). And on that point, your version of contains fail, because we have no guarantee that it will be present in other implementations since there is no requirement of that in the DOM. Neither Tasman, Trident, Presto (Opera) nor the the KHTML engine expose HTMLElement as an object, and they are not doing anything wrong in not exposing it.
brothercake
05-05-2004, 02:28 AM
Very true - but you can use it as an expando of an actual HTML element, which is what I've been doing with it.
Stevezilla00
07-13-2006, 06:28 PM
Jkd, your code seems very clean & efficient, but I am having trouble implementing it in IE.
In Firefox (which doesn't need this handling anyway since child onmouseout events don't trigger parent onmouseout events), it works great. In IE 6 and 7b3, however, I get the JavaScript error "'HTMLElement' is undefined". Any idea what I'm doing wrong, or how to fix it? Thanks!
Stevezilla00
07-13-2006, 09:01 PM
I've gotten it working, but I've discovered along the way that the div which runs the function after an onmouseout event cannot be relative positioned or have a relative-positioned parent unless it itself is absolute positioned or is contained by an absolute-positioned parent lower down the chain than any relative-positioned parents. If the div doesn't meet these conditions, IE continues to behave as if there was no special handling (i.e. child onmouseout events trigger the parent onmouseout event).
Stevezilla00
07-13-2006, 09:33 PM
If anyone knows how to get around the relative positioning issue in IE, that would be great (and save me a ton of hassle).
Here's an example:
<html>
<head>
<style type="text/css" media="all">
.outline {border:2px dotted #8fb5f3; background-color:#fafcff;}
</style>
<script type="text/javascript">
HTMLElement.prototype.contains = function(node) {
if (node == null) {
return false;
} else if (node == this) {
return true;
} else {
return this.contains(node.parentNode);
}
}
function mouseOutContentBlock(oElement, eEvent) {
if (!oElement.contains(eEvent.relatedTarget || eEvent.toElement)) {
oElement.className='';
}
}
</script>
</head>
<body>
<div style="position:relative" onmouseover="this.className='outline';" onmouseout="mouseOutContentBlock(this, event)">
<p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Duis ultricies. Curabitur euismod magna vel elit. In ut odio eu justo laoreet pellentesque. Fusce metus risus, vehicula ac, tincidunt rhoncus, euismod eget, leo. Curabitur eget risus. Vestibulum feugiat. Mauris hendrerit erat eget justo. Donec accumsan viverra risus. Etiam lectus urna.</p>
<p>Sed rhoncus malesuada nunc. Proin eget massa eget est egestas pulvinar. Ut tempor ligula et erat. Vivamus dignissim mollis urna. Pellentesque et urna. Curabitur massa. Maecenas semper ultrices lacus. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Proin ac lacus. Vestibulum et erat. Aliquam eros.</p>
</div>
</body>
</html>
Run the above code in IE and hover over the empty space between the two paragraphs... The style should flicker on and off, as the onmouseout events for the paragraphs trigger their parent div's onmouseout. Remove the "position:relative", however, and the problem goes away.
Is there any way to make this work while keeping position:relative? Thanks!
Vexiphne
05-27-2008, 05:08 PM
i know this is some seriously ancient thread but i've had one hell of a time finding anything to fix this.
Firefox = works
Safari = works
IE7 = bombs
HTMLElement.prototype.contains = function(node) {
if (node == null)
return false;
if (node == this)
return true;
else
return this.contains(node.parentNode);
}
function mouseFunction(evt,func,pid) {
var pearl = document.getElementById('purl'+pid);
if (!pearl.contains(evt.relatedTarget || evt.toElement)) {
if (func == 'showproduct') {
document.getElementById('purl'+pid).innerHTML = document.getElementById('product'+pid+'-info').innerHTML;
document.getElementById('product'+pid+'-overlay').setAttribute('class','productover');
document.getElementById('product'+pid+'-overlay').setAttribute('className','productover');
}
if (func == 'hideproduct') {
document.getElementById('product'+pid+'-overlay').setAttribute('className','productnormal');
document.getElementById('product'+pid+'-overlay').setAttribute('class','productnormal');
document.getElementById('purl'+pid).innerHTML = '';
}
}
else { alert ('ie sux'); }
}
go figure - the alert goes off.
No errors, nothing. It acts like there isnt even an inch of javascript on the page.
Is there an updated "IE" code for this?
Thanks for all the help
vBulletin® v3.8.2, Copyright ©2000-2012, Jelsoft Enterprises Ltd.