Trigger onmouseover event programmatically in JavaScript
Asked Answered
H

9

68

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

Heptamerous answered 9/2, 2010 at 10:40 Comment(6)
Have you tried this? The onmouseover event should fire on the parent event also thanks to event propagation.Lyra
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.Heptamerous
@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.Heptamerous
@fearofawhackplanet: I apologize for my arrogant comment, deleted. (factual part: "element overlapping != element nesting")Djokjakarta
1-liner version (tested in Chrome console) element.dispatchEvent(e=(document.createEvent( 'Events' )),e.initEvent( "mouseenter", true, false ),e)Heidiheidie
@Heptamerous 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.Titos
T
-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.

Ternion answered 9/2, 2010 at 10:44 Comment(5)
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.Heptamerous
I'm not sure whether this ever worked, but I believe it should at least be without the 'on' prefix.Candytuft
Doesn't work Uncaught TypeError: e.previousElementSibling.onmouseover is not a function(…)Darcie
@Heptamerous 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.Hostility
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.Krause
B
88
const mouseoverEvent = new Event('mouseover');

whateverElement.dispatchEvent(mouseoverEvent);
Binate answered 12/3, 2018 at 23:32 Comment(5)
Scrolled down hoping I would find something like thisGoddaughter
Sometimes mouseover doesn't work but mouseenter does. const evt = new Event('mouseenter'); whateverElement.dispatchEvent(evt);Skeie
nice, these are different eventsBinate
not working on mobileDecigram
@YehudaZvi get a new device, this is 2024 already!Binate
A
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" );
Autoharp answered 1/12, 2012 at 0:17 Comment(3)
For what it's worth, initEvent is deprecated and should not be relied upon according to MDN 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);Prebendary
this was the only solution which worked for me on Chrome in 2021 :)Nelson
var evObj = document.createEvent( 'Events' );evObj.initEvent( EventName, true, false ); document.getElementById( ElementId ).dispatchEvent( evObj ); This works like a charm :)Blasien
C
37

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 }));
Coenosarc answered 15/8, 2019 at 4:3 Comment(0)
A
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 );
        }
    }
}
Autoharp answered 2/12, 2012 at 1:7 Comment(1)
Don't use a setTimeout as eval! Instead, use Function.prototype.bind.Wordsmith
A
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 );
        }
    }
}
Autoharp answered 6/12, 2012 at 16:48 Comment(0)
C
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.

Cyte answered 24/8, 2012 at 2:52 Comment(2)
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.Cyte
Perhaps because the OP says they are looking for a solution "in plain Javascript"?Seagrave
C
0
​<a href="index.html" onmouseover="javascript:alert(0);" id="help"​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​>help</a>​​​​​​​​​​​​​​​​​​​​​​​​​​​

​document.getElementById('help').onmouseover();​​​​​​​
Cribbs answered 7/7, 2010 at 5:59 Comment(0)
T
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')
}
Toneytong answered 9/2, 2023 at 18:44 Comment(0)
T
-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.

Ternion answered 9/2, 2010 at 10:44 Comment(5)
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.Heptamerous
I'm not sure whether this ever worked, but I believe it should at least be without the 'on' prefix.Candytuft
Doesn't work Uncaught TypeError: e.previousElementSibling.onmouseover is not a function(…)Darcie
@Heptamerous 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.Hostility
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.Krause

© 2022 - 2024 — McMap. All rights reserved.