views:

108

answers:

2

The General Problem


So 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.getElementById(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.

A: 

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.

Lekensteyn
Well firstly I added event to `onmouseover` too but it's just not better :|.
CIRK
A: 

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 }
heb
I want to have that 0.5 second delay.
CIRK