Contact   •   Articles   •   Products   •   Search

Rick Strahl's Web Log

Wind, waves, code and everything in between...
ASP.NET • C# • HTML5 • JavaScript • AngularJs

HREF links and javascript: Navigation


I seem to make this mistake  repeatedly: I have a hyperlink on a page and rather than execute another URL I want it to execute a small bit of JavaScript code. Something like click a button and hide another control on the page:

 

<a href="javascript:document.getElementById('DragPanel').style.display='none';">Click</a>

 

This might seem reasonable, but if you run this code you’ll quickly find out that this doesn’t work. Well, the control hides alright – but so does everything else <s>. The entire page in fact navigates and it returns a new DOM with none as the value. Slightly unexpected eh? Not quite sure how the browser detects this value, but in any case it navigates the page somewhere I don't want it to navigate to.

 

There are a few ways around this. First you can navigate with a function call:

 

<a href="javascript:DoSomething();">Click</a>

<script>

function DoSomething()

{

    document.getElementById('DragPanel').style.display='none';

}

</script>

 

This works and appropriately runs the code in the function without navigating the page. However, you have to be careful not to return any values from the function or else you get the same behavior I showed above where the result value becomes the new document displayed.

 

Since calling a function is OK, you can do something like the following too:

 

<a href="javascript:{document.getElementById('DragPanel').style.display='none';}">Click</a>

 

Which essentially defines an inline function and lets you execute the desired code. One downside to this is that the execution context changes so the the this pointer doesn’t point at the control any longer, but at the Window. It’s basically an anonymous function that’s being called on the fly and so it becomes a browser global functon tied to Window.

 

If you do need the this pointer you can use another approach:

 

<a href="javascript:{}" onclick="document.getElementById('DragPanel').style.display='none';alert(this.id);" id="MyLink">Click</a>

 

You might wonder why the null function {} link? You need something valid in the HREF attribute in order for the Anchor to show as a link, but yet something that doesn't actually navigate the page. Leaving the HREF=”” blank doesn’t do it because that basically means to re-load the current page. The null function does nothing, yet is a valid value  which is exactly what's needed here. javascript:; also works.

 

By using onclick() you’re bypassing the navigation operation of the link so you can just use plain in context code to what you need.  As you can see in the snippet you can also access the this point in this way.

 

It’s actually easier to just use a plain label with onclick, but often times you do want the link behavior - the proper  mouse pointer, link highlighting etc. - and so it’s still frequently reqiured to use HREF links (or ASP.NET LinkButtons) for link display. If you are using an ASP.NET LinkButton you can set the NavigateUrl with the javascript:{} link. Otherwise operationis identical.

Make Donation
Posted in JavaScript  Ajax  

The Voices of Reason


 

# DotNetSlackers: HREF links and javascript: Navigation


Bertrand Le Roy
January 01, 2007

# re: HREF links and javascript: Navigation

You don't need and shouldn't include the javascript protocol for an event handler such as onclick. It should only be used for properties that are urls such as href. It happens to work because "anything:" is just interpreted as a label definition in JavaScript.

Rick Strahl
January 01, 2007

# re: HREF links and javascript: Navigation

Thanks for catching that - that was a typo from the code I used. I actually caught that but I apparently forgot to fix it in the post <s>. Fixed now.

S
January 01, 2007

# re: HREF links and javascript: Navigation

javascript:void(0); is the more preferred placeholder.

Matthijs van der Vleuten
January 01, 2007

# re: HREF links and javascript: Navigation

The link appearance can be created by using the appropriate CSS styles. There's no need to abuse href for that.

Marty
January 02, 2007

# re: HREF links and javascript: Navigation

Better:
<a href="#" onclick="document.getElementById('DragPanel').style.display='none';">Click</a>

Best:
<span onclick="document.getElementById('DragPanel').style.display='none';" class="anchorstyle">Click</span>

Rick Strahl
January 02, 2007

# re: HREF links and javascript: Navigation

Well CSS kinda works, but you don't quite get the same behavior as an anchor link. Hover color for example...

Sylvain Bujold
January 02, 2007

# re: HREF links and javascript: Navigation

Actually, one way to get your first tag to work is to catch the returned value in a var like this:
href="javascript:var x = document.getElementById('div4').style.display='none';"


Not that this is a good idea to do in code but this shows how you can type some javascript code in the address bar for debugging/testing without screwing up your page.

Ben Strackany
January 02, 2007

# re: HREF links and javascript: Navigation

Good post. Nowadays I use

<a href="javascript:void(0);" onclick="some_javascript_stuff">click me!</a>


Using href="#" and href="javascript:some_javascript" gave me too much trouble in the past.

BTW, IMO labels w/ special CSS shouldn't be used as "fake" links because screen readers, text browsers, and other non-standard browsers won't necessarily interpret them as actionable items. For accessibility, it's better to use tags for what they're "designed" to do, i.e. links & buttons for actions & navigation, UL & OL for lists of things, etc.

Now granted, if you want to actually hide the link from screen readers, then CSS and/or labels would be a way to ensure that.

John Rutherford
January 02, 2007

# re: HREF links and javascript: Navigation

I always do this:

<a href="" onclick="someFunction(); return false;">Click Here!<a/>


I hate seeing "javascript:someFunction();" in the status bar when you hover over the link.

"Return false" ensures that the browser doesn't navigate to the href or even reload the page.

Matthijs van der Vleuten
January 02, 2007

# re: HREF links and javascript: Navigation

Marty, <a href="#" onclick="..."> is not good at all. This will cause the viewport to move to the top of the page, when Javascript is disabled.

Rick Strahl, using the span example Marty provided, try the following CSS:

SPAN.anchorstyle { color=blue; }
SPAN.anchorstyle:hover { color=red; }

Matthijs van der Vleuten
January 02, 2007

# re: HREF links and javascript: Navigation

Whoops. That should be color:blue; of course.

Rick Strahl
January 02, 2007

# re: HREF links and javascript: Navigation

Matthijs, interesting. It requires the SPAN.anchorstyle, but .anchorstyle alone doesn't work. I had tried the latter but it didn't work in any browser. The full tag works in FireFox and Opera, but not in IE :-{.

I'd argue it's easier to coerce an Anchor tag <s>...

Rick Strahl
January 03, 2007

# re: HREF links and javascript: Navigation

John - HREF="" is definitely not a good way to do this. Browser behavior differs, but it will likely navigate the page either reloading or going to the current default path. I just did a quick check: FireFox reloads the current page. IE loads the local path (same as /virtual/). Opera doesn't navigate.

The return false; in the onclick has no effect on the navigation aspect. So - unpredictable behavior in browsers. Don't do it <s>...

Marty
January 03, 2007

# re: HREF links and javascript: Navigation

Matthijs: A slight modification of the internal anchor for long pages:
<a href="#Click" name="Click" onclick="document.getElementById('DragPanel').style.display='none';return false;">Click</a>


span :hover doesn't work in <IE7. You'd have to add onmouseover/addmouseout event handlers :(

The "proper" way of doing this would probably be to inject the entire anchor including text with javascript, because without javascript this function won't work. It "gracefully degrades", what a great term :)
    var a= document.createElement("a");
    a.href="#Click";
    a.name="Click";
    a.onclick= myFunction; //supply your function name
    var t = document.createTextNode("Click");
    a.appendChild(t);
    document.getElementById("hook").appendChild(a); //hook to hang the new command on

Michael Schwarz
January 04, 2007

# re: HREF links and javascript: Navigation

My way to do it is like this:

<a href="javascript:;" onclick="...">xxx</a>


;)

Carl Camera
January 04, 2007

# Javascript Suggestions

Rick, while I have no problem with your syntax I thought I'd point out these shortcomings: (1) Inline javascript is not a best practice. (2) Not all browsers support getElementById (3) you have no fallback when javascript is disabled.

See: http://www.robertnyman.com/2006/03/23/ajax-javascript-and-accessibility/ for pointers on usability, portability, and maintainability of javascript.

Rick Strahl
January 04, 2007

# re: HREF links and javascript: Navigation

Carl - good points. However, if JavaScript is enabled you're not really going to be able to do anything about executing JavaScript in the first place - so that point is kind of moot. getElementById is pretty old though and supported pretty widely. If it doesn't work in the browser's JavaScript implementation it's almost more likely that there's no JavaScript parser in the browser at all <s>...

Thanks for the link though - these are good points to consider!

Dave Bleeker
January 15, 2007

# re: HREF links and javascript: Navigation

Interresting points. You could also set up the events after the page is loaded of course, by getting the anchors using getElementById or getElementsByTagName and setAttribute.

Bertrand Le Roy - I have read this argument before and noticed there are a lot of discussion about it. Still I'm not sure why it wouldn't be good to use this since it will work in all browsers.

Thanks for your view of a solution on this.

Jason
February 22, 2007

# re: HREF links and javascript: Navigation

I see people use href="javascript:void(0);" all the time in the href, so why not just wrap the function call itself in the void: href="javascript:void(functionCall());"?

Wouldn't that have the same effect without requiring the use of onclick?

Rick Strahl
September 30, 2007

# re: HREF links and javascript: Navigation

Jason, the problem with specifying javascript in the the Href is that it may still navigate the page and go to a new window frame. I've seen inconsistent results with this so generally it's a bad idea to run javascript code in the HREF IMHO.

Michael
October 17, 2007

# re: HREF links and javascript: Navigation

Just to add my piece. I always use:
  <a href="javascript:HideItem('DragPanel')" onclick="HideItem('DragPanel'); return false;">Click</a>


The reason is that you allow the user to see what the link will do in the browser status-bar. This is important since the other options will show 'void();', '#' or other confusing information which can cause the user to skip the link.
Basically the onclick is not really needed here, but is supplied for compatibility. This is used in many websites and tested in the important browsers.

Sure, the function return value is still important. My point is just to be transparant and show the user what the link does.

Dave Haynes
February 05, 2009

# re: HREF links and javascript: Navigation

To get the .anchorstyle:hover to work properly, add an appropriate doctype to the page:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

HQ
April 23, 2009

# re: HREF links and javascript: Navigation

thank you! that's exactly the answer I am looking for.
 


West Wind  © Rick Strahl, West Wind Technologies, 2005 - 2015