determine if function called as a result of a native browser event

events, javascript

Solution

The DOM Level 3 Events spec introduced the `isTrusted` property on event objects. This property is set to `true` when the event is generated as the result of a user action, and `false` when it's been created e.g. via `createEvent`:

Events that are generated by the user agent, either as a result of user interaction, or as a direct result of changes to the DOM, are trusted by the user agent with privileges that are not afforded to events generated by script through the `DocumentEvent.createEvent("Event")` method, modified using the `Event.initEvent()` method, or dispatched via the `EventTarget.dispatchEvent()` method.

Currently, it seems only IE9+ and Firefox support this property though. Here's a working example (obviously you'll have to run it in one of the supported browsers):

var elem = document.getElementById("example");
elem.addEventListener("click", function (e) {
    alert(e.isTrusted);
}, false);

var evt = document.createEvent("MouseEvents");
evt.initMouseEvent("click", true, true, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
elem.dispatchEvent(evt);

That will alert `false` when the simulated event is fired straight away, and `true` any time you actually click on the element.

Problem

Is there a way to determine if a given function is called as a result of a native browser event? In modern browsers if you call the function `window.open(...)` from a scope chain that originated with a click handler a page will open with no problem. However if you try to call it directly, the browser will generate a popup warning. So the browser keeps track of the execution context and somehow flags it so the first use of the function succeeds. Without the presence of this flag it blocks the second use. Is there any way to get access to this flag to internally block certain functions from executing if they are called directly as opposed to from a real native browser event. I've looked at event object my functions receive but I can't spot anything that's different between a real native event, and an event generated by triggering the event manually. Is what I want actually possible?

Original source