47

How can I manually trigger a right click using Javascript?

I can do this with jQuery but I can only use pure Javascript in this case.

Abs
  • 56,052
  • 101
  • 275
  • 409

3 Answers3

37

Create an event using the CustomEvent constructor, or (when it is not supported), create an event using document.createEvent with as argument the string "HTMLEvents" (because you're going to create a click event). Then, use the initEvent method to create a click event.

Finally, use the dispatchEvent method to fire the event. If you're using IE, the fireEvent method has to be used instead.

If you want to trigger the rightclick event, contextmenu, use the code below:

var element = document.getElementById('yourElement');
if (window.CustomEvent) {
    element.dispatchEvent(new CustomEvent('contextmenu'));
} else if (document.createEvent) {
    var ev = document.createEvent('HTMLEvents');
    ev.initEvent('contextmenu', true, false);
    element.dispatchEvent(ev);
} else { // Internet Explorer
    element.fireEvent('oncontextmenu');
}
Rob W
  • 341,306
  • 83
  • 791
  • 678
  • 1
    @Abs, somehow I interpreted "right click" as "correctly implement click". Updating answer in a second, the concept is the same. **EDIT** Do you mean `contextmenu` event, or a real right click? – Rob W Oct 27 '11 at 10:46
  • 1
    thanks for the link - but it doesn't seem to work for me? I tried it on several browsers. Here is an example: http://jsfiddle.net/9gbd4/ – Abs Oct 27 '11 at 12:12
  • 5
    @Abs You should invoke the `dispatchEvent` method on the element which should get a rightclick event. Instead of `click`, you should use `mousedown`, because the `click` event normally don't capture rightclick events. **Fiddle: http://jsfiddle.net/9gbd4/1/**. Note: If you're intending to show a context menu using JavaScript, give up. JavaScript cannot trigger such behaviour. – Rob W Oct 27 '11 at 12:44
  • @RobW I believe that you can, in fact, trigger a native browser context menu by firing this event. I've done and tested just this, actually. The tricky bit, as far as I can tell, is that you can only do it during another mouse event. Specifically, I've been able to stop a right click event from occurring on one element and in the same handler fire the context menu on a different element. Hope that helps. – Patrick Sep 12 '12 at 02:40
  • @Patrick I'd be glad to see a demo. The following demo, based on the previous demo and your hints does not show a context menu (Chrome 21): http://jsfiddle.net/9gbd4/2/ – Rob W Sep 12 '12 at 20:57
  • @RobW I'll try to work one up. Right now, the code is extremely tangled in proprietary stuff, but I'll try to create fiddle or similar that demonstrates the effect. To further clarify, I'm specifically stopping a right click on a transparent high Z-Index, absolutely positioned element and refiring the context menu bit on the appropriate element that is actually visible under the cursor on the layer below. It's essentially a left click catching screen. I don't know if any of those specifics matter. – Patrick Sep 12 '12 at 21:55
  • Note that `initEvent` is now deprecated. – automaton Mar 12 '15 at 16:32
21

Another variant, this time using the MouseEvent API which is a bit more modern. In my case I actually send all three events mouseup/mousedown/contextmenu:

var element = document.getElementById("yourElement");
var ev1 = new MouseEvent("mousedown", {
    bubbles: true,
    cancelable: false,
    view: window,
    button: 2,
    buttons: 2,
    clientX: element.getBoundingClientRect().x,
    clientY: element.getBoundingClientRect().y
});
element.dispatchEvent(ev1);
var ev2 = new MouseEvent("mouseup", {
    bubbles: true,
    cancelable: false,
    view: window,
    button: 2,
    buttons: 0,
    clientX: element.getBoundingClientRect().x,
    clientY: element.getBoundingClientRect().y
});
element.dispatchEvent(ev2);
var ev3 = new MouseEvent("contextmenu", {
    bubbles: true,
    cancelable: false,
    view: window,
    button: 2,
    buttons: 0,
    clientX: element.getBoundingClientRect().x,
    clientY: element.getBoundingClientRect().y
});
element.dispatchEvent(ev3);
jmiserez
  • 2,991
  • 1
  • 23
  • 34
1

Taking Rob W example, I haven't tried it but, You need to make the event object and pass it along when firing the event. for the right click pass event.button = 2;

var element = document.getElementById("yourElement"),
  ev;
if(document.createEvent ) {
    ev = document.createEvent("MouseEvents");
    ev.initMouseEvent("click", true, false, window,0,0,0,0,0,false,false,false,false,2,null);
    element.dispatchEvent(ev);
} else {
    ev = document.createEventObject();
    ev.button = 2;
    element.fireEvent('onclick', ev);
}

Updated according to mdn initMouseEvent. Good luck :)

Cu7l4ss
  • 556
  • 1
  • 8
  • 19
  • `ev.which` cannot be changed, as it's a read-only property (at least in Firefox 3.6.23). – Rob W Oct 27 '11 at 10:56
  • You were right, it's button but I'm not sure it's making it. since I have no idea what @Abs is after – Cu7l4ss Oct 27 '11 at 11:03
  • @Abs it's working both in IE and every other browser I checked. the captured event object would be set with button = 2 – Cu7l4ss Oct 27 '11 at 11:25
  • @Rob W For some odd reason then this code works. and the ev.button in the mozilla case is a left over. But I checked, this code works, double checked it. – Cu7l4ss Oct 27 '11 at 12:15
  • I tried this in Firefox 3.2 and I get the error `setting a property that has only a getter` in my firebug. – Abs Oct 27 '11 at 12:23
  • @Abs yes I forgot to remove the ev.button = 2 in the w3c way... try removing that line – Cu7l4ss Oct 27 '11 at 13:47
  • `initMouseEvent` was deprecated a while ago. – Downhillski Mar 08 '17 at 02:41