Thursday, 15 April 2010

Don't use "javascript:" pseudo-protocol

I see many web pages uses "javascript:" pseudo-protocol in the "href" attribute of "a" (anchor) element.

For example:

<a href="javascript:myFunc();">Click me!</a>

But that's not a good practice. IE6 produces some side effects when using "javascript:" pseudo-protocol (newer versions of IE seems to solve the problems). One side effect is that it blocks "gif" animation (you can try and see that)!
The main problem is that using "javascript:" pseudo-protocol shifts IE6 into "wait state" and it blocks some functionality like mentioned "gif" animation but there are more, for example it changes execution context - "this" doesn't reference current element, but window:

<a href="javascript:myFunc(this);" onclick="myFunc(this)">Click me!</a>

If function is executed from "onclick", "this" is reference to "a" element, while in "href" attribute, "this" is reference to the window.

Anyway, there is no need to use "javascript:" pseudo-protocol in the first place. Anchor should be used for it's purpose, so if you want to execute some JavaScript function when user clicks on the element's text, you can use some other element ("span" for example), add "onclick" attribute which executes desired JavaScript function and style it if you want it to look like anchor:

<span class="anchor" onclick="myFunc();">Click me!</span>

You can also use anchor element to execute JavaScript code. But, here comes the problem with "javascript:" pseudo-protocol - users add "onclick" attribute to "a" element, but then they don't get desired behavior:

<a href="#" onclick="myFunc();">Click me!</a>

This way, when user click on the anchor, document is scrolled to the top of the document since in "href" attribute there is just "#" (a fragment) character - which has semantical meaning of the top of the document (that's why scrolling happens). And here comes the "javascript:" pseudo-protocol to solve that problem - but it introduces another.

There is (are) better alternative(s).

You can just return "false" in "onclick" attribute:

<a href="#" onclick="myFunc(); return false;">Click me!</a>

This way, event won't be propagated and there won't be scrolling to the top of the document.

Another way (which I prefer since it's semantically correct) is to add reference to current anchor element:

<a href="#anch" name="anch" onclick="myFunc();">Click me!</a>

This way there will be scrolling to this anchor, but that's what anchors are used for (and you'll execute JavaScript function).

And the last way is already mentioned - use "span" element insted of "a" element.

No comments:

Post a Comment