Event listeners as html attributes

I need to use JS function from content page in my extension. I added html attribute “onclick” with script but reviewer said I have to use addEventListener:

Please use “click” addEventListener rather than “onclick” attributes

How can I avoid of using “onclick” to run page functions?

Use event.preventDefault() and event.stopPropagation()

For insance,

document.addEventListener('click', function(e) {
    e.stopPropagation();
    e.preventDefault();
}, false);

Advanced lesson: That should do the trick. But some sites have click listeners on bubbling down, so in that case you would want to set the third argument to true.

Above are only needed if the target is normally clickable e.g. a link. For a normal element, they are not needed.

Example:

var span = document.createElement('span');
span.addEventListener('click', aFunction);

function aFunction() {
  // some code
}

The actual question appears to be about the use of the onclick attribute vs a fully-fledge event listener. I’m not sure where preventDefault() and stopPropagation() come into it. I’m very confused.

On the original question: the use of the onclick attribute is generally frowned upon as a security risk since it requires the definition of a string which is then parsed into javascript. Depending where this string came from, it is a potential means of injecting malware. At one extreme, if the attribute is hard-coded, for example in an xul file, then it is relatively safe, but adding one in javascript, and most especially constructing one out of other strings, is risky and would be rejected by a reviewer. A second disadvantage is that setting an onclick attribute from javascript risks overwriting one that has been set in the html or by other javascript.

The safe way to add an event listener using javascript is to use addEventListener(). addEventListener() can accept a function or an object implementing the eventListener interface as its second parameter. The eventListener interface simply requires a handleEvent() method. For example:
element.addEventListener(“click”, function() { do anything you want here, except use eval() });
element.addEventListener(“click”, {handleEvent() : function(event) { your function here });

Of course you wouldn’t normally use an anonymous object inline like this, but would have a static object used to handle many different events. It can even be an object used for other purposes such as a wrapper for many functions, so long as one of them is called handleEvent.

1 Like

Thank you for detailed response.
From attribute I can call functions from the site’s scripts, but they are not in handleEvent()'s scope, is there no way to call it “legally”?

What scope is your addon running in? You may have to specify the content window explicitly to access the site’s functions.