56

In the 1990s, there was a fashion to put Javascript code directly into <a> href attributes, like this:

<a href="javascript:alert('Hello world!')">Press me!</a>

And then suddenly I stopped to see it. They were all replaced by things like:

<a href="#" onclick="alert('Hello world!')">Press me!</a>

For a link whose sole purpose is to trigger Javascript code, and has no real href target, why is it encouraged to use the onclick property instead of the href property?

zneak
  • 134,922
  • 42
  • 253
  • 328

10 Answers10

56

The execution context is different, to see this, try these links instead:

<a href="javascript:alert(this.tagName)">Press me!</a> <!-- result: undefined -->
<a href="#" onclick="alert(this.tagName)">Press me!</a> <!-- result: A -->

javascript: is executed in the global context, not as a method of the element, which is usually want you want. In most cases you're doing something with or in relation to the element you acted on, better to execute it in that context.

Also, it's just much cleaner, though I wouldn't use in-line script at all. Check out any framework for handling these things in a much cleaner way. Example in jQuery:

$('a').click(function() { alert(this.tagName); });
Nick Craver
  • 623,446
  • 136
  • 1,297
  • 1,155
  • 6
    just a quick clarification - when you call javascript:this from the href attribute, it's a reference to the window DOM object. – matt lohkamp Mar 19 '10 at 18:33
  • 1
    Thanks for explaining the difference then suggesting a better way. – zneak Mar 19 '10 at 19:53
  • 1
    I find it interesting that the focus of the answer which the community favors - and which was selected - focuses on the inconveniences that using the `javascript:` protocol creates _for the developer_ as opposed to its impact on the quality of the deliverables... makes me think of the elevator test; http://www.codinghorror.com/blog/2007/09/can-your-team-pass-the-elevator-test.html – Richard JP Le Guen Mar 19 '10 at 20:24
  • @Richard - This also has the advantage of being in an external and cached file, not downloaded as part of the page every round...I'd argue for many reasons it's better for both quality and convenience to the developer. – Nick Craver Mar 19 '10 at 20:44
  • @Nick Craver - this is true... I was musing just as much on the phrasing as the content; it feels to me like that comes off as a footnote/afterthought. Not to say I disagree with any of your points :) – Richard JP Le Guen Mar 19 '10 at 21:00
19

Actually, both methods are considered obsolete. Developers are instead encouraged to separate all JavaScript in an external JS file in order to separate logic and code from genuine markup

The reason for this is that it creates code that is easier to maintain and debug, and it also promotes web standards and accessibility. Think of it like this: Looking at your example, what if you had hundreds of links like that on a page and needed to change out the alert behavior for some other function using external JS references, you'd only need to change a single event binding in one JS file as opposed to copying and pasting a bunch of code over and over again or doing a find-and-replace.

Levi Hackwith
  • 9,232
  • 18
  • 64
  • 115
10

Couple of reasons:

  1. Bad code practice:
    The HREF tag is to indicate that there is a hyperlink reference to another location. By using the same tag for a javascript function which is not actually taking the user anywhere is bad programming practice.

  2. SEO problems:
    I think web crawlers use the HREF tag to crawl throughout the web site & link all the connected parts. By putting in javascript, we break this functionality.

  3. Breaks accessibility:
    I think some screen readers will not be able to execute the javascript & might not know how to deal with the javascript while they expect a hyperlink. User will expect to see a link in the browser status bar on hover of the link while they will see a string like: "javascript:" which might confuse them etc.

  4. You are still in 1990's:
    The mainstream advice is to have your javascript in a seperate file & not mingle with the HTML of the page as was done in 1990's.

HTH.

Sunny
  • 6,286
  • 2
  • 25
  • 27
  • I don't believe SEO is a valid argument as they're very well able to find out which links they can follow and which they can't. I'll buy your argument about screen readers (I'd sure love to hear a computer voice read out loud Javascript code), but the status bar thing seems exaggerated to me. – zneak Mar 19 '10 at 19:20
  • 1
    @zneak - perhaphs I should replace the status bar comment from "might confuse them" to "might irritate them". From personal experience, I like to Shift+click/Ctrl+click on links to open them in a new window when I dont want to taken off the current page & when that breaks, I want to go find the developer who broke it in the first place :) – Sunny Mar 19 '10 at 19:30
  • +1 for the bad code practice, href tag have not been created to indicate the trigger of a JS code. – Adriano Apr 23 '14 at 08:55
7

I open lots of links in new tabs - only to see javascript:void(0). So you annoy me, as well as yourself (because Google will see the same thing).

Another reason (also mentioned by others) is that different languages should be separated into different documents. Why? Well,

  • Mixed languages aren't well supported by most IDEs and validators. Embedding CSS and JS into HTML pages (or anything else for that matter) pretty much destroys opportunities to have the embedded language checked for correctness statically. Sometimes, the embedding language as well. (A PHP or ASP document isn't valid HTML.) You don't want syntax errors or inconsistencies to show up only at runtime.
  • Another reason is to have a cleaner separation between the kinds of things you need to specify: HTML for content, CSS for layout, JS usually for more layout and look-and-feel. These don't map one to one: you usually want to apply layout to whole categories of content elements (hence CSS) and look and feel as well (hence jQuery). They may be changed at different times that the content elements are changed (in fact the content is often generated on the fly) and by different people. So it makes sense to keep them in separate documents as well.
reinierpost
  • 8,425
  • 1
  • 38
  • 70
  • Voted up mainly for the first point. Trying to open a link in a new tab only to see `javascript:void(0)` in the address bar drives me *crazy*. – Tyler McHenry Mar 19 '10 at 19:06
  • I was more talking about Javascript code that only affects the calling page. I don't like to see `javascript:void(0)` either. – zneak Mar 19 '10 at 19:22
5

Using the javascript: protocol affects accessibility, and also hurts how SEO friendly your page is.

Take note that HTML stands for Hypter Text something something... Hyper Text denotes text with links and references in it, which is what an anchor element <a> is used for.

When you use the javascript: 'protocol' you're misusing the anchor element. Since you're misusing the <a> element, things like the Google Bot and the Jaws Screen reader will have trouble 'understanding' your page, since they don't care much about your JS but care plenty about the Hyper Text ML, taking special note of the anchor hrefs.

It also affects the usability of your page when a user who does not have JavaScript enabled visits your page; you're breaking the expected functionality and behavior of links for those users. It will look like a link, but it won't act like a link because it uses the javascript protocol.

You might think "but how many people have JavaScript disabled nowadays?" but I like to phrase that idea more along the lines of "How many potential customers am I willing to turn away just because of a checkbox in their browser settings?"

It boils down to how href is an HTML attribute, and as such it belongs to your site's information, not its behavior. The JavaScript defines the behavior, but your never want it to interfere with the data/information. The epitome of this idea would be the external JavaScript file; not using onclick as an attribute, but instead as an event handler in your JavaScript file.

Richard JP Le Guen
  • 28,364
  • 7
  • 89
  • 119
4

Short Answer: Inline Javascript is bad for the reasons that inline CSS is bad.

leepowers
  • 37,828
  • 23
  • 98
  • 129
4

The worst problem is probably that it breaks expected functionality.
For example, as others has pointed out, open in new window/tab = dead link = annoyed/confused users.

I always try to use onclick instead, and add something to the URL-hash of the page to indicate the desired function to trigger and add a check at pageload to check the hash and trigger the function.

This way you get the same behavior for clicks, new tab/window and even bookmarked/sent links, and things don't get to wacky if JS is off.

In other words, something like this (very simplified):

For the link:

onclick = "doStuff()"

href = "#dostuff"

For the page:

onLoad = if(hash="dostuff") doStuff();
Navnath Godse
  • 2,233
  • 2
  • 23
  • 32
3

I typically have a landing page called "EnableJavascript.htm" that has a big message on it saying "Javascript must be enabled for this feature to work". And then I setup my anchor tags like this...

<a href="EnableJavascript.htm" onclick="funcName(); return false;">

This way, the anchor has a legitimate destination that will get overwritten by your Javascript functionality whenever possible. This will degrade gracefully. Although, now a days, I generally build web sites with complete functionality before I decide to sprinkle some Javascript into the mix (which all together eliminates the need for anchors like this).

Using onclick attribute directly in the markup is a whole other topic, but I would recommend an unobtrusive approach with a library like jQuery.

Josh Stodola
  • 81,538
  • 47
  • 180
  • 227
2

Also, as long as we're talking about deprecation and semantics, it's probably worth pointing out that '</a>' doesn't mean 'clickable' - it means 'anchor,' and implies a link to another page. So it would make sense to use that tag to switch to a different 'view' in your application, but not to perform a computation. The fact that you don't have a URL in your href attribute should be a sign that you shouldn't be using an anchor tag.

You can, alternately, assign a click event action to nearly any html element - maybe an <h1>, an <img>, or a <p> would be more appropriate? At any rate, as other people have mentioned, add another attribute (an 'id' perhaps) that javascript can use as a 'hook' (document.getElementById) to get to the element and assign an onclick. That way you can keep your content (HTML) presentation (CSS) and interactivity (JavaScript) separated. And the world won't end.

matt lohkamp
  • 2,174
  • 3
  • 28
  • 47
  • Perhaps `` would be more appropriate than `

    ` since it's semantically meaningless. But I get the idea.

    – zneak Mar 19 '10 at 19:12
1

I think it has to do with what the user sees in the status bar. Typically applications should be built for failover in case javascript isn't enabled however this isn't always the case.

With all the spamming that is going on people are getting smarter and when an email looks 'phishy' more and more people are looking at the status bar to see where the link will actually take them.

Remember to add 'return false;' to the end of your link so the page doesn't jump to the top on the user (unless that's the behaviour you are looking for).

RDL
  • 7,865
  • 3
  • 29
  • 32