Friday, May 29, 2015

Variations in JavaScript from Anchor Tags

Don't click on this anchor.
This came up again for me the other day, and I couldn't remember all the rules. Let's say you want to call a JavaScript function when someone clicks on a link on your web page. Do you make the href attribute in the anchor tag a javascript: URI? Do you set the href to "#" and set the onclick attribute to your function call? Is it better to add an event handler instead of using the onclick attribute?

Maybe there's no right answer (I know, some people will tell you that using the javascript: URI in the href is the wrong answer because it mixes the layout and logic...but in small projects I don't get too hung up on those things). But you should be aware of the different behaviors in the function depending on which method you choose.

I set up a demo page so I can remind myself which is which.

<!doctype html>

<html lang="en">
<head>
  <meta charset="utf-8">
  <title>Link Functions</title>
</head>

<body>

  <p><a id="a" href="javascript:doSomething(event, this);">JavaScript in the href</a></p>

  <p><a id="b" href="#" onclick="doSomething(event, this)">JavaScript onclick</a></p>

  <p><a id="c" href="#">Handler added by jQuery</a></p>

</body>

<script src="https://code.jquery.com/jquery-1.11.2.min.js"></script>
<script>

function doSomething(evt, src) {

    // what is "this" now?
    console.log(this);

    // what event got us here?
    console.log(evt);

    // DOM source of the click
    console.log(src);

}

$(function() {

    $("#c").click(doSomething);

});

</script>

</html>

If you click on the first link, the javascript: URI version, inside the function this will reference the Window object. There is no event object, and the source of the click also appears to be the Window object. This form is certainly the least useful. It executes your code, but you really get no insight into where the click came from.

The second link, which uses the onclick attribute, also results in the Window object being this inside the function. But the event is populated with a MouseEvent and the source node is the anchor tag. That's all good information.

The third form, which set the click event handler using jQuery, also gives good information but in a slightly different way. Inside the function, this refers to the anchor tag instead of the Window. The event object is a jQuery event object, which wraps the original event. This is nice because jQuery events tend to be more standard across different browsers.

The bottom line is that the second and third forms are better because they give you more complete information about the click. But they do so in different ways - ways of which you must be aware! The first form should probably be avoided in most cases.

I'll probably have to refer back to this post myself in a few months to remember the rules. One of the best things about writing a blog is that it documents information for your future self. Often I search my own posts for some bit of information that I know I wrote about once but can't remember.

My comics don't really contain any useful information but sometimes I look back at them too. You should look at the one for today:

Amphibian.com comic for 29 May 2015