1

I would like to listen to a click event on a particular element and then dispatch it to a link element while keeping in mind if the meta key was hold or not.

For instance:
Let's say I have a table of elements. When the user clicks on a row I would like to follow a link, but I would like the link to be opened in a new tab if the user had his /ctrl key pressed.

It seems simple but I found out this was tricky... (As I didn't succeed to do it!)

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
Nima Izadi
  • 996
  • 6
  • 18

1 Answers1

1

The DOM Event API already provides all you need, assuming you need only to remember the modifier keys from a legitimate user action.

When using addEventListener to catch an event, simply take the parameter, which is a DOMEvent instance, that is passed to your handler function, and resend it to your target element with dispatchEvent  :)

Indeed, a DOMEvent instance encapsulates its source environment. More specifically here, a MouseEvent knows which keys were pressed when it was fired.


Demo: try clicking the link in this JSfiddle while holding down (or ctrl if not on a Mac), for example.

For a complete reference, here is the used code:

var button = document.getElementById('source'),
    target = document.getElementById('target');

function handler(evt) {
    target.dispatchEvent(evt); // that's all the magic it takes
}

button.addEventListener(
    'click', // listen to a click event
    handler,
    false // no capture, i.e. do not catch events before children
);​

You may also find this complete reference on DOM events useful  :)

MattiSG
  • 3,796
  • 1
  • 21
  • 32
  • I've already tried that but don't you get this error: Uncaught Error: DISPATCH_REQUEST_ERR: DOM Events Exception 1? – Nima Izadi Sep 16 '12 at 18:23
  • @NimaIzadi I had tested only with Safari 5, in which it worked. Indeed, Chrome 21 throws a `DISPATCH_REQUEST_ERR`… and FF 14 throws `NS_ERROR_ILLEGAL_VALUE`. Quite interesting. I'm trying to investigate some more. – MattiSG Sep 16 '12 at 19:10
  • 1
    `DISPATCH_REQUEST_ERR` comes from the fact that the event is [already dispatched](http://www.w3.org/TR/2006/WD-DOM-Level-3-Events-20060413/events.html#Events-EventTarget-dispatchEvent). I tried to `stopPropagation()` but that doesn't change anything. Hence, I think only of two ways. First is to clone the event through `createEvent` and [`initMouseEvent`](https://developer.mozilla.org/en-US/docs/DOM/event.initMouseEvent) (annoying to write, but can be in a helper function); this will probably not open links in the background as asked, due to the `isTrusted` attribute… – MattiSG Sep 16 '12 at 19:29
  • 1
    …(ref. for `isTrusted` [here](http://www.w3.org/TR/DOM-Level-3-Events/#trusted-events)). This should be tested in each browser though. Second way, to be tested too, and a bit ugly: add a timeout and `dispatch` the event later, after it has finished bubbling. – MattiSG Sep 16 '12 at 19:30
  • Great! setTimeout works visibly on Webkit (Chrome 21 & Safari 6) but not on FF. It doesn't do anything on FF... (neither throw `NS_ERROR_ILLEGAL_VALUE`) – Nima Izadi Sep 16 '12 at 19:52