64

Is there a way to programmatically trigger the onmouseover event in plain JavaScript? or "extract" the method from the onmouseover event to call it directly?

eg

<div id="bottom-div" onmouseover="myFunction('some param specific to bottom-div');">
    <div id="top-div" onmouseover="????????"></div>
</div>

top-div is above bottom-div, so the onmouseover won't get fired in bottom-div. i need a way of calling myFunction('some param specific to bottom-div'); from top-div

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
fearofawhackplanet
  • 52,166
  • 53
  • 160
  • 253
  • 2
    Have you tried this? The onmouseover event _should_ fire on the parent event also thanks to event propagation. – Tatu Ulmanen Feb 09 '10 at 10:43
  • ok i didn't think about that, sorry it's a slightly bad example because in my app they aren't actually nested elements. the top div is absolutely positioned over a number of other elements. – fearofawhackplanet Feb 09 '10 at 11:09
  • @Piskvor: I was trying to reduce a very complex piece of html to a simple example and I made a mistake. Sorry if that offends you. – fearofawhackplanet Jul 07 '10 at 08:07
  • 2
    @fearofawhackplanet: I apologize for my arrogant comment, deleted. (factual part: "element overlapping != element nesting") – Piskvor left the building Jul 07 '10 at 08:19
  • 1-liner version (tested in Chrome console) element.dispatchEvent(e=(document.createEvent( 'Events' )),e.initEvent( "mouseenter", true, false ),e) – Jan Jul 22 '19 at 12:02
  • @fearofawhackplanet I usually recommand *not* to give in to peer pressure, but just this time, I suggest you consider changing your accepted answer on that question. – SteeveDroz Nov 03 '20 at 13:56

9 Answers9

82
const mouseoverEvent = new Event('mouseover');

whateverElement.dispatchEvent(mouseoverEvent);
givehug
  • 1,863
  • 1
  • 14
  • 19
  • 4
    Scrolled down hoping I would find something like this – ESR Jan 08 '19 at 23:14
  • 7
    Sometimes mouseover doesn't work but `mouseenter` does. `const evt = new Event('mouseenter'); whateverElement.dispatchEvent(evt);` – brianf Feb 27 '19 at 10:04
39

This worked for me in IE9 at least. Should be cross-browser compatible or close to it...

function FireEvent( ElementId, EventName )
{
    if( document.getElementById(ElementId) != null )    
    {   
        if( document.getElementById( ElementId ).fireEvent ) 
        {
            document.getElementById( ElementId ).fireEvent( 'on' + EventName );     
        }
        else 
        {   
            var evObj = document.createEvent( 'Events' );
            evObj.initEvent( EventName, true, false );
            document.getElementById( ElementId ).dispatchEvent( evObj );
        }
    }
}

For onmouseover example, call the function like this

FireEvent( ElementId, "mouseover" );
Jonathan
  • 531
  • 6
  • 3
  • 10
    For what it's worth, `initEvent` is deprecated and should not be relied upon according to MDN https://developer.mozilla.org/en-US/docs/Web/API/Event/initEvent .. and example that could be in the `else` block above is: `var event = new MouseEvent(EventName, { 'view': window, 'bubbles': true, 'cancelable': true }); document.getElementById(ElementId).dispatchEvent(event);` – james Apr 05 '16 at 13:16
  • this was the only solution which worked for me on Chrome in 2021 :) – Csa77 Feb 21 '21 at 20:02
  • var evObj = document.createEvent( 'Events' );evObj.initEvent( EventName, true, false ); document.getElementById( ElementId ).dispatchEvent( evObj ); This works like a charm :) – Mahmoud Aly Oct 17 '21 at 02:14
32

For me following worked:

​document.getElementById('xyz').dispatchEvent(new MouseEvent('mouseover', { 'bubbles': true }));

Also:

​document.getElementById('xyz').dispatchEvent(new MouseEvent('mouseover', { 'view': window, 'bubbles': true, 'cancelable': true }));
Kishan
  • 1,630
  • 13
  • 19
7

Without going into too much detail, I had an img with rollovers, i.e. mouseout/overs that set the img src to hidden form values (or this could have done in a different context with gloabl variables). I used some javascript to swap both of my over/out image values and I called the called FireEvent( ElementId, "mouseover" ); to trigger the change. My javascript was hiding / displaying elements on the page. This caused the cursor to sometimes be over the img I used to trigger the event - which was the same as the one I was swapping out, and sometimes the cursor was not over the img after the click.

Mouseover/out does not fire unless you exit and re-enter an element, so after my event was triggered the mouseover/out needed "retriggering" to account for the new cursor position. Here is my solution. After I hide / display various page elements, and to do my img src swapping as described, I call the function RefreshMouseEvents( ElementId ) instead of FireEvent( ElementId, "mouseover" ).

This works in IE9 (not sure about other browsers).

function RefreshMouseEvents( ElementId )
{
    FireEvent( ElementId, 'mouseover' );
    setTimeout( "TriggerMouseEvent( '" + ElementId + "' )" , 1 );
}

function TriggerMouseEvent( ElementId )
{
    if( IsMouseOver( ElementId, event.clientX, event.clientY ) )
        FireEvent( ElementId, 'mouseover' );
    else    
        FireEvent( ElementId, 'mouseout' );
}

function IsMouseOver( ElementId, MouseXPos, MouseYPos )
{
    if( document.getElementById(ElementId) != null )    
    {
        var Element = document.getElementById(ElementId);   
        var Left  = Element.getBoundingClientRect().left, 
            Top   = Element.getBoundingClientRect().top,
            Right = Element.getBoundingClientRect().right,
            Bottom  = Element.getBoundingClientRect().bottom;       
        return ( (MouseXPos >= Left) && (MouseXPos <= Right) && (MouseYPos >= Top) && (MouseYPos <= Bottom))    
    }
    else
        return false;
}

function FireEvent( ElementId, EventName )
{
    if( document.getElementById(ElementId) != null )    
    {   
        if( document.getElementById( ElementId ).fireEvent ) 
        {
            document.getElementById( ElementId ).fireEvent( 'on' + EventName );     
        }
        else 
        {   
            var evObj = document.createEvent( 'Events' );
            evObj.initEvent( EventName, true, false );
            document.getElementById( ElementId ).dispatchEvent( evObj );
        }
    }
}
Jonathan
  • 531
  • 6
  • 3
7

I had to revise my RefreshMouseEvents set of functions after more testing. Here is the seemingly perfected version (again only IE9 tested):

function RefreshMouseEvents( ElementId ) 
{
    FireEvent( ElementId, 'mouseover' );
    setTimeout( "TriggerMouseEvent( '" + ElementId + "', '" + event.clientX + "', '" + event.clientY + "' )", 1 );
}

function TriggerMouseEvent( ElementId, MouseXPos, MouseYPos )
{
    if( IsMouseOver( ElementId, (1*MouseXPos), (1*MouseYPos) ) )
        FireEvent( ElementId, 'mouseover' );
    else    
        FireEvent( ElementId, 'mouseout' );
}

function IsMouseOver( ElementId, MouseXPos, MouseYPos )
{
    if( document.getElementById(ElementId) != null )    
    {
        var Element = document.getElementById(ElementId);   
        var Left  = Element.getBoundingClientRect().left, 
            Top   = Element.getBoundingClientRect().top,
            Right = Element.getBoundingClientRect().right,
            Bottom  = Element.getBoundingClientRect().bottom;       
        return ( (MouseXPos >= Left) && (MouseXPos <= Right) && (MouseYPos >= Top) && (MouseYPos <= Bottom))    
    }
    else
        return false;
}

function FireEvent( ElementId, EventName )
{
    if( document.getElementById(ElementId) != null )    
    {   
        if( document.getElementById( ElementId ).fireEvent ) 
        {
            document.getElementById( ElementId ).fireEvent( 'on' + EventName );     
        }
        else 
        {   
            var evObj = document.createEvent( 'Events' );
            evObj.initEvent( EventName, true, false );
            document.getElementById( ElementId ).dispatchEvent( evObj );
        }
    }
}
Jonathan
  • 531
  • 6
  • 3
3

I needed to do something similar, but I'm using jQuery, and I found this to be a better solution:

Use jQuery's trigger function.

$j('#top-div' ).trigger( 'mouseenter' );

You can also add parameters to it if you need to. See the jQuery documentation on .trigger.

thephatp
  • 1,479
  • 1
  • 20
  • 37
  • 1
    I find it hilarious when people down-vote an answer and don't say way. So, to whoever down-voted my answer, please explain why so that I can learn something new. I don't suggest my answer is the best, but it worked for me. If you found a problem with it, please add a comment so that we can know why, or better yet, so I can improve my answer. – thephatp Dec 24 '15 at 19:13
  • 12
    Perhaps because the OP says they are looking for a solution "in plain Javascript"? – bigsee Dec 19 '18 at 22:04
0
​<a href="index.html" onmouseover="javascript:alert(0);" id="help"​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​>help</a>​​​​​​​​​​​​​​​​​​​​​​​​​​​

​document.getElementById('help').onmouseover();​​​​​​​
Reigel Gallarde
  • 64,198
  • 21
  • 121
  • 139
0

I was working with Angular and trying to do a similar thing. I fall on this answer from StackOverflow Click here Basically the idea is to add and remove the hover class

public addHoverOnClick() {
    const yourElement = document.getElementById('elementID') as HTMLElement;
    yourElement .classList.add('hover')

}

public removeHoverOnClick() {
    const yourElement = document.getElementById('elementID') as HTMLElement;
    yourElement .classList.remove('hover')
}
-30

You would do it something like this:

document.getElementById('top-div').onmouseover();

However, as mentioned in the comments, it would be worth testing before being considered an issue.

Yacoby
  • 54,544
  • 15
  • 116
  • 120
  • i didn't realise it was so simple! i'm sure i've tried to do similar with onclick before and it doesn't work. maybe my memory is bad. – fearofawhackplanet Feb 09 '10 at 11:20
  • 3
    I'm not sure whether this ever worked, but I believe it should at least be without the 'on' prefix. – Ja͢ck Feb 23 '13 at 09:20
  • 21
    Doesn't work `Uncaught TypeError: e.previousElementSibling.onmouseover is not a function(…)` – Green May 27 '16 at 10:34
  • 4
    @fearofawhackplanet Please consider accepting a different answer. This one won’t work in _most_ cases and is discouraged — it will only work when a function is bound to the `onmouseover` property, but `addEventListener` is preferred to that. This answer doesn’t work for this standard API, the most upvoted one, however, will work for any approach. – Sebastian Simon Apr 16 '18 at 00:36
  • What this does is that it calls the function that was previously assigned to "onmouseover" (if it was assigned, otherwise you get the `Uncaught TypeError`). This is why `.mouseover()` will not work (unless you did assign a function to it). But in the end, you are not triggering a hover - you are just calling the handler. – Christian May 17 '23 at 11:25