158

I know about the document.form.button.click() method. However, I'd like to know how to simulate the onclick event.

I found this code somewhere here on Stack Overflow, but I don't know how to use it :(

function contextMenuClick()
{
  var element= 'button';
  var evt = element.ownerDocument.createEvent('MouseEvents');

  evt.initMouseEvent('contextmenu', true, true, element.ownerDocument.defaultView,
                     1, 0, 0, 0, 0, false, false, false, false, 1, null);

  element.dispatchEvent(evt);
}

How do I fire a mouse click event using JavaScript?

Awesome
  • 5,689
  • 8
  • 33
  • 58
Nok Imchen
  • 2,802
  • 7
  • 33
  • 59

8 Answers8

231

(Modified version to make it work without prototype.js)

function simulate(element, eventName)
{
    var options = extend(defaultOptions, arguments[2] || {});
    var oEvent, eventType = null;

    for (var name in eventMatchers)
    {
        if (eventMatchers[name].test(eventName)) { eventType = name; break; }
    }

    if (!eventType)
        throw new SyntaxError('Only HTMLEvents and MouseEvents interfaces are supported');

    if (document.createEvent)
    {
        oEvent = document.createEvent(eventType);
        if (eventType == 'HTMLEvents')
        {
            oEvent.initEvent(eventName, options.bubbles, options.cancelable);
        }
        else
        {
            oEvent.initMouseEvent(eventName, options.bubbles, options.cancelable, document.defaultView,
            options.button, options.pointerX, options.pointerY, options.pointerX, options.pointerY,
            options.ctrlKey, options.altKey, options.shiftKey, options.metaKey, options.button, element);
        }
        element.dispatchEvent(oEvent);
    }
    else
    {
        options.clientX = options.pointerX;
        options.clientY = options.pointerY;
        var evt = document.createEventObject();
        oEvent = extend(evt, options);
        element.fireEvent('on' + eventName, oEvent);
    }
    return element;
}

function extend(destination, source) {
    for (var property in source)
      destination[property] = source[property];
    return destination;
}

var eventMatchers = {
    'HTMLEvents': /^(?:load|unload|abort|error|select|change|submit|reset|focus|blur|resize|scroll)$/,
    'MouseEvents': /^(?:click|dblclick|mouse(?:down|up|over|move|out))$/
}
var defaultOptions = {
    pointerX: 0,
    pointerY: 0,
    button: 0,
    ctrlKey: false,
    altKey: false,
    shiftKey: false,
    metaKey: false,
    bubbles: true,
    cancelable: true
}

You can use it like this:

simulate(document.getElementById("btn"), "click");

Note that as a third parameter you can pass in 'options'. The options you don't specify are taken from the defaultOptions (see bottom of the script). So if you for example want to specify mouse coordinates you can do something like:

simulate(document.getElementById("btn"), "click", { pointerX: 123, pointerY: 321 })

You can use a similar approach to override other default options.

Credits should go to kangax. Here's the original source (prototype.js specific).

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
TweeZz
  • 4,779
  • 5
  • 39
  • 53
  • 7
    Credits should go to kangax, as noted in my answer. I did make it library agnostic :) – TweeZz May 27 '11 at 22:30
  • How to pass mouse coordinates to this script? – Dmitry Nov 12 '12 at 10:27
  • 1
    I will edit the post and add an example of how you could pass in mouse coordinates.. – TweeZz Nov 12 '12 at 16:51
  • @TweeZz I was trying to use this function to click a link that normally opens a modal view (I'm using twitter bootstrap). Unfortunately, however, the function does not open the modal, but instead it redirects to a new page having as content the modal view. Is it possibile to make it work with modal windows (the link looks like this: ``)? – don Dec 12 '12 at 08:26
  • 1
    I transformed this into a CoffeeScript module for easy inclusion in your projects here: https://github.com/joscha/eventr – Joscha Jan 11 '13 at 16:32
  • note: this code sets the relatedTarget attribute of the event to always be the input element, which may cause some subtle bugs if you're simulating mouseover and mouseout events – C. Reed Jun 02 '13 at 10:21
  • @TweeZz Does this work for keyDown ? I need to simulate a keypress and other keyboard events. do you any other code that does this for me ? – Mohsen Sarkar Feb 18 '14 at 08:20
  • No, it doesn't work for key events. Only `html events` and `mouse events` are handled. – TweeZz Feb 18 '14 at 09:10
  • Hmm, can anyone confirm it does _not_ work for IE9 and lower? – TweeZz Mar 03 '15 at 17:19
  • 1
    how is this different from $(el).click(), as your solution works for me, jquery option doesn't – Silver Ringvee Sep 20 '16 at 07:41
  • @TweeZz How click on object from d3.js e.g.circle and to simulate click on coordinates(100,100) and then drag it to (200,200); and then release on (200,200) point? – Arthur Alunts Jul 21 '20 at 10:30
  • This was fantastic. I was using a code snippet I found online which set the event type to 'Events' instead of 'MouseEvents' and couldn't figure out why React wouldn't see the event. jQuery's .click() and .trigger('click') didn't work either. It's been years since I did real JS work (I'm mostly a C++ guy) and I spent hours on this problem before finding this post. This worked. Thanks! – Dave Dopson Feb 09 '21 at 06:19
  • My refactored [version](https://gist.github.com/ken107/c56c6a69bf3c18995af8a02ec875900c) – Sarsaparilla Aug 20 '21 at 16:53
73

An easier and more standard way to simulate a mouse click would be directly using the event constructor to create an event and dispatch it.

Though the MouseEvent.initMouseEvent() method is kept for backward compatibility, creating of a MouseEvent object should be done using the MouseEvent() constructor.

var evt = new MouseEvent("click", {
    view: window,
    bubbles: true,
    cancelable: true,
    clientX: 20,
    /* whatever properties you want to give it */
});
targetElement.dispatchEvent(evt);

Demo: http://jsfiddle.net/DerekL/932wyok6/

This works on all modern browsers. For old browsers including IE, MouseEvent.initMouseEvent will have to be used unfortunately though it's deprecated.

var evt = document.createEvent("MouseEvents");
evt.initMouseEvent("click", canBubble, cancelable, view,
                   detail, screenX, screenY, clientX, clientY,
                   ctrlKey, altKey, shiftKey, metaKey,
                   button, relatedTarget);
targetElement.dispatchEvent(evt);
Derek 朕會功夫
  • 92,235
  • 44
  • 185
  • 247
  • This seems to fail when the A element that I want to be clicked has href="javascript:void(0)" and it responds to another click handler that has been attached to the object. – deejbee Mar 29 '17 at 08:31
  • is there a quick way to get common events? I notice I can raise click easily on a button, but is there no standard "mouseenter", "mouseleave" evt that I can just reference rather than creating a new mouseevent like done above? – James Joshua Street Jun 18 '19 at 02:41
  • Those custom properties won't be accessible in your event-listener. – holmberd Jun 04 '21 at 15:08
58

Here's a pure JavaScript function which will simulate a click (or any mouse event) on a target element:

function simulatedClick(target, options) {

  var event = target.ownerDocument.createEvent('MouseEvents'),
      options = options || {},
      opts = { // These are the default values, set up for un-modified left clicks
        type: 'click',
        canBubble: true,
        cancelable: true,
        view: target.ownerDocument.defaultView,
        detail: 1,
        screenX: 0, //The coordinates within the entire page
        screenY: 0,
        clientX: 0, //The coordinates within the viewport
        clientY: 0,
        ctrlKey: false,
        altKey: false,
        shiftKey: false,
        metaKey: false, //I *think* 'meta' is 'Cmd/Apple' on Mac, and 'Windows key' on Win. Not sure, though!
        button: 0, //0 = left, 1 = middle, 2 = right
        relatedTarget: null,
      };

  //Merge the options with the defaults
  for (var key in options) {
    if (options.hasOwnProperty(key)) {
      opts[key] = options[key];
    }
  }

  //Pass in the options
  event.initMouseEvent(
      opts.type,
      opts.canBubble,
      opts.cancelable,
      opts.view,
      opts.detail,
      opts.screenX,
      opts.screenY,
      opts.clientX,
      opts.clientY,
      opts.ctrlKey,
      opts.altKey,
      opts.shiftKey,
      opts.metaKey,
      opts.button,
      opts.relatedTarget
  );

  //Fire the event
  target.dispatchEvent(event);
}

Here's a working example: http://www.spookandpuff.com/examples/clickSimulation.html

You can simulate a click on any element in the DOM. Something like simulatedClick(document.getElementById('yourButtonId')) would work.

You can pass in an object into options to override the defaults (to simulate which mouse button you want, whether Shift/Alt/Ctrl are held, etc. The options it accepts are based on the MouseEvents API.

I've tested in Firefox, Safari and Chrome. Internet Explorer might need special treatment, I'm not sure.

Ben Hull
  • 7,524
  • 3
  • 36
  • 56
  • This worked great for me, on Chrome, where the elements don't seem to have the click() event. – Howard M. Lewis Ship Oct 25 '11 at 21:39
  • This is great -- except `type: options.click || 'click'` should probably be `type: options.type || 'click'`. – Elliot Winkler May 11 '12 at 20:20
  • The problem with this solution is it won't click contained elements. eg. `
    simulatedClick(document.getElementById('outer'));` won't click the inner element.
    – dwjohnston Sep 30 '15 at 22:14
  • 1
    That's not how event bubbling works, though - if you click an outer element, it's _ancestors_ receive the click event as it bubbles up, but its children don't. Imagine if your outer `div` contained a button or a link - you wouldn't want a click on the outer to trigger a click on the inner element. – Ben Hull Oct 02 '15 at 22:15
  • 5
    Don't use the `||` operator for cases like this, because whoops, `canBubble:options.canBubble || true,` always evaluates to true now, and apparently no one will notice it for 5 years. – Winchestro Jan 28 '16 at 16:29
  • Thank you! It seems it is necessary to use the exact number of parameters if you want to simulate a mouse event with the "Shift" or "Control" keys. Some other people suggested it the following way, but it won't work: `event.initMouseEvent('mousewheel', {shiftKey: true})` It only works the way you suggested: `event.initMouseEvent('mousewheel', true, true,window,0,0,0,0,0,0,0,true )` – gearcoded Nov 02 '20 at 16:43
14

Based on Derek's answer, I verified that

document.getElementById('testTarget')
  .dispatchEvent(new MouseEvent('click', {shiftKey: true}))

works as expected even with key modifiers. And this is not a deprecated API, as far as I can see. You can verify on this page as well.

Wizek
  • 4,854
  • 2
  • 25
  • 52
  • I encountered a situation where the `click()` function or `trigger("click")` in jQuery did not work, but the `dispatchEvent()` function worked well. Impressive! – xia xiongjun Jul 09 '23 at 06:02
12

From the Mozilla Developer Network (MDN) documentation, HTMLElement.click() is what you're looking for. You can find out more events here.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Lewis
  • 14,132
  • 12
  • 66
  • 87
  • 2
    @Ercksen As the MDN page says, it only fires the element's click event when used with elements that support it (e.g. one of the types). – Christophe Feb 24 '16 at 02:25
5

You can use elementFromPoint:

document.elementFromPoint(x, y);

supported in all browsers: https://caniuse.com/#feat=element-from-point

hanshenrik
  • 19,904
  • 4
  • 43
  • 89
GIA
  • 1,400
  • 2
  • 21
  • 38
1

Don't rely on deprecated API features. All browsers support the example below. See docs and example here

if (document.createEvent) {

    // Create a synthetic click MouseEvent
    let event = new MouseEvent("click", {
     bubbles: true,
     cancelable: true,
     view: window
    });

    // Dispatch the event.
    link.dispatchEvent(event);

}
Gregory Bologna
  • 270
  • 1
  • 6
  • 20
-2

JavaScript Code

   //this function is used to fire click event
    function eventFire(el, etype){
      if (el.fireEvent) {
        el.fireEvent('on' + etype);
      } else {
        var evObj = document.createEvent('Events');
        evObj.initEvent(etype, true, false);
        el.dispatchEvent(evObj);
      }
    }

function showPdf(){
  eventFire(document.getElementById('picToClick'), 'click');
}

HTML Code

<img id="picToClick" data-toggle="modal" data-target="#pdfModal" src="img/Adobe-icon.png" ng-hide="1===1">
  <button onclick="showPdf()">Click me</button>
BERGUIGA Mohamed Amine
  • 6,094
  • 3
  • 40
  • 38