The General Problem
Imagine a dropdown menu for example and when you mouse over
on a link the dropdown is popping up.
But as you can read on the article below, there are problems with it, when you mouse over on a link(for some browsers everything inside the element) the box is dissapearing. The problem comes from event bubbling
.
In my document onmouseover
and onmouseout
are delayed with 0.5 seconds
and you can see that sometimes the element starts to vibrate, because of this problem.
--------------
| Layer |.onmouseout = doSomething;
| -------- |
| | Link | ----> We want to know about this mouseout
| | | |
| -------- |
| -------- |
| | Link | |
| | ----> | but not about this one
| -------- |
--------------
---->: mouse movement
Read this article for understanding better:
www.quirksmode.org - Javascript - Mouse Events
Quirksmode solution
function doSomething(e) {
if (!e) var e = window.event;
var tg = (window.event) ? e.srcElement : e.target;
if (tg.nodeName != 'DIV') return;
var reltg = (e.relatedTarget) ? e.relatedTarget : e.toElement;
while (reltg != tg && reltg.nodeName != 'BODY')
reltg= reltg.parentNode
if (reltg== tg) return;
// Mouseout took place when mouse actually left layer
// Handle event
}
My document
You can find my full document here:
JS Bin - My documents
You can find the original document without mouseEvent(e)
function here:
JS Bin - Original
Mouseover on the button then mouse over the box then quickly mouseout and quickly come back to box then it will start to vibrate. (On Firefox 3.6 Windows 7)
Javascript
<script type="text/javascript">
function mouseEvent(e) {
if (!e) var e = window.event;
var tg = (window.event) ? e.srcElement : e.target;
if (tg.nodeName != 'DIV') return;
var reltg = (e.relatedTarget) ? e.relatedTarget : e.toElement;
while (reltg != tg && reltg.nodeName != 'BODY')
reltg= reltg.parentNode
if (reltg== tg) return;
// Mouseout took place when mouse actually left layer
// Handle event
}
function toggleByType(id, type, e){
setTimeout(function(){
var element = document.getE开发者_开发知识库lementById(id);
if(element.style.display == type){
mouseEvent(e);
element.style.display = 'none';
} else {
element.style.display = type;
}
}, 500);
}
</script>
HTML
<div class="box-container" onmouseover="toggleByType('box','block');" onmouseout="toggleByType('box','block', event);">
<a href="#" class="box-bridge">Show Box</a>
<div id="box" class="box" style="display:none;">
Mouse out and this will dissapear.
<br />
<a href="#">Roll over to have problems</a>
</div>
</div>
My Problem
The solution what quirksmode is giving sounds logical however I don't know how to use the function
I tried in a lots of ways what I posted is just one, but I don't get it, so I would be very happy if you could help me to make this work.
You're missing event
in the onmouseover
attribute:
onmouseover="toggleByType('box','block', event);"
But, you've still a 500ms delay before the menu shows up.
Why not using pure CSS? With the :hover meta-tag you can easily set-up this menu without using any JS. Works with all modern browsers (except pre-IE 7).
Example:
.box { display: none }; .box-container:hover .box { display: block }
精彩评论