Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

onmouseout not fired when element goes away

I have a mouseover event which triggers a tooltip; I would like this tooltip to go away when the mouse is removed. onmouseout works well, except when the element goes away.

Here is a distilled example which uses background changes instead of tooltips (so you can easily run it):

<div id="bar">
  <div onmouseover="document.bgColor='gray'" onmouseout="document.bgColor='white'" style="border:1px solid black;">
   <span onclick="document.getElementById('bar').innerHTML = ''">Remove me</span>
  </div>
</div>

The problem is this: when I click "Remove me", my mouse is no longer "over" the div, but the onmouseout doesn't trigger, because it has gone away. What I would like is for this example to revert to a white background when I click "Remove me".

There is an obvious solution, which I would like to avoid. I do not want the onclick handler which removes the element to manually "fix up" the document. This is because there may be arbitrarily many handlers which could remove the div with the onmouseout. In general, all of the mouseout and removal handlers may be generated dynamically, and need to know about each other. To complicate things further, I might have a case where removable elements are nested in each other, and any of them could be removed. (I might be able to remove this constraint, but it will take a little work.)


Here is an example of a solution that could work: on mouseover, register the modal dialogue as "active"; then whenever elements are removed, iterate over all modal dialogues and look for ones which are no longer in the document. But this requires me to keep a global store of dialogues, and takes time O(n*m), where n is the number of active dialogues, and m is how deeply nested the dialogue is in the DOM. Furthermore, I need to run this operation whenever I remove elements, even if it's pretty obvious nothing is affected.

Here is another solution that could work: if you can implement an onremovedfromdocument event, then we just copy the onmouseout handler to be the onremovedfromdocument event, and the example will work correctly too. (I hear jQuery might support this, but I need to interoperate with non-jQuery code.)

Here is yet another possible solution: have each modal dialogue repeatedly poll to see if its parent is in the document. When it is not, have it commit seppuku. But polling is really ugly. (I guess I'd be willing to do this if there's nothing better!)

Here's another idea: use event capture to allow the onmouseout element to capture the click element first, and setup a timer to check if it is still in the document after the click is done.


For reference, here is what I'm really trying to do: I have a JS widget which builds a complicated tree structure. Many of the edits to the widget involve clicking some button in the tree, which then adds or deletes from the tree (possibly deleting itself.) However, some of the nodes need more complicated edit procedures, so I would like to bring up a tooltip with instructions and possibly more buttons when the user mouses over them, or even keep the dialogue around if the user clicks them. But the user may change his mind and decide to delete the node, or any parent of the node, in which case the dialogue should go away. You can view an implementation of what I currently have here, where the dialogues are being manually created. I would like to start using a nice tooltip library, but all of them have the bug which I described above.

like image 597
Edward Z. Yang Avatar asked May 22 '12 22:05

Edward Z. Yang


People also ask

When mouseout event fired?

The mouseout event is fired at an Element when a pointing device (usually a mouse) is used to move the cursor so that it is no longer contained within the element or one of its children.

What is the difference between onmouseleave and onmouseout?

The mouseout event triggers when the mouse pointer leaves any child elements as well the selected element. The mouseleave event is only triggered when the mouse pointer leaves the selected element.

Is a event that happens when the user moves the mouse away from an element?

The onmouseleave event occurs when the mouse pointer is moved out of an element.

What does Onmouseout mean?

Definition and Usage The onmouseout event occurs when the mouse pointer is moved out of an element, or out of one of its children.


1 Answers

On modern browsers, there is the DOMNodeRemoved event. So:

var div = document.getElementsByTagName('div')[0];
div.addEventListener('DOMNodeRemoved', function(e){
    document.bgColor='white';
});​

http://jsfiddle.net/HX88L/

The bad thing is, that event is already deprecated. The replacement for the so-called mutation events doesn't look like it's ready to use yet. MDN doc page is still just a stub.

like image 77
bfavaretto Avatar answered Sep 25 '22 01:09

bfavaretto