Making Opera honour return false in onclick handler

This post is more than 12 years old.

The Opera browser persistently refuses to honour “return false” in an onclick handler, and is quite possibly the only web browser that does this. Because I don’t usually add event handlers inline any more, I haven’t noticed this defect until now, but it just bit me today.

I usually add click event handlers that squelch the event like this:

function triggerAndSuppress(event) {
    event.preventDefault();
    doSomething();
}

element.addEventListener("click", triggerAndSuppress, false);

This works properly in Opera (and all other standards-based browsers; of course, older IE browsers have a different event model). But for some reason, Opera just refuses to accept that the next construct should work the same way:

<a href="#" onclick="doSomething(); return false;">do something</a>

When I write code that builds up HTML structure using DOM createElement() calls, this isn’t a concern. However, for a recent Google Maps project, I had to build the HTML as a string and append it to some existing HTML text. To have a link that triggered a JavaScript function and didn’t make the page navigate somewhere, I needed to write an inline handler that used return false. This worked OK in every browser I tested, except for Opera.

To resolve this problem, I had to make use of the way that events bubble up from inner to outer elements (in the standard event model), and the ability to add custom data properties to elements. The following code works by marking the links in question with a distinct data property, hooking the click event on the DIV element that contains my Google Map, and checking to see whether the click event came from the link I’m targetting. The HTML was essentially this:

<a href="#" data-fix-opera="1" 
    onclick="doSomething(); return false;">do something</a>

And to make Opera play ball:

if (window.opera) {
    mapDiv.addEventListener("click", function(event) {
        if (event.target.getAttribute("data-fix-opera")) {
            event.preventDefault();
        }
    }, false);
}

Take that, Opera; job is done the same way as in the other browsers, whether you like it or not.