SitePoint Sponsor

User Tag List

Results 1 to 9 of 9
  1. #1
    SitePoint Evangelist winterheat's Avatar
    Join Date
    Aug 2007
    Posts
    508
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    difference between href="#" and href="javascript:void(0)" and 3 other methods

    If we have a link and we want it to execute a javascript function, there seems to be 5 ways at least:

    HTML Code:
    <a onclick="foo()">Next Image</a>
    HTML Code:
    <a href="#" onclick="foo()">Next Image</a>
    HTML Code:
    <a href="javascript:foo()">Next Image</a>
    HTML Code:
    <a href="javascript:void(0)" onclick="foo()">Next Image</a>
    HTML Code:
    <a href="#" onclick="foo(); return false;">Next Image</a>
    method 1 usually won't change the mouse cursor to a "hand cursor", so maybe it is not as desirable in some cases.

    method 2 seems to cause the page to shift to a new location sometimes on IE 6 and IE 7. (to top of page?)

    method 3 ... should work... but is it an old school way and should be avoided for modern browsers?

    method 4 should work well... except in article http://blog.reindel.com/2006/08/11/a...void-the-void/
    the author seems to suggest it may break sometimes and try never to use href="javascript:[anything]"

    method 5 may work the best? according to the article above, that may be the best way as it doesn't use href="javascript:[something]" and the return false part will cause the href="#" not to be evaluted, so that's the best way? thanks very much!
    Last edited by winterheat; Aug 14, 2008 at 18:27.

  2. #2
    Unobtrusively zen silver trophybronze trophy
    paul_wilkins's Avatar
    Join Date
    Jan 2007
    Location
    Christchurch, New Zealand
    Posts
    14,729
    Mentioned
    104 Post(s)
    Tagged
    4 Thread(s)
    Method 6: Where the link points to a useful location. The called function can also effectively control whether the default link action is performed or not.

    It's best to link to an appropriate location, which is beneficial when javascript isn't available, and helps search engines as well. If there is no appropriate location then a button may be more useful instead.

    Code html4strict:
    <a href="nextimage.jpg" onclick="return foo()">Next Image</a>

    Code javascript:
    function foo() {
        ...
        return false;
    }

    Then we move away from inline event registration to traditional event registration

    Method 7: Traditional event registration by identifier

    Code html4strict:
    <a id="doFoo" href="nextimage.jpg">Next Image</a>

    Best practice for speeding up your web site is to place scripts at the bottom of the body, just before the </body> tag. Not only does this speed up page rendering, but it also makes it easier to work with page elements.

    If you don't place the script at the end of the body, you will need to use some kind technique to run the script after the page finishes loading.

    Code javascript:
    document.getElementById('doFoo').onclick = foo;
    function foo() {
        ...
        return false;
    }

    Method 8: Traditional event registration by class name, perhaps the most robust technique to use.

    Code html4strict:
    <a class="doFoo" href="nextimage.jpg">Next Image</a>


    Code javascript:
    var els = document.getElementsByTagName('a');
    var el;
    var i;
    for (i = 0; i < els.length; i += 1) {
        el = els[i];
        if (el.className === 'doFoo') {
            el.onclick = foo;
        }
    }
    function foo() {
        ...
        return false;
    }

    Method 9: Advanced event registration, allows multiple events to be attached to the same element, but rarely is this actually required.

    Code html4strict:
    <a id="doFoo" href="nextimage.jpg">Next Image</a>

    Code javascript:
    var el = document.getElementById('doFoo');
    if (el.addEventListener) {
        el.addEventListener('click', foo, false);
    } else if (el.attachEvent) {
        el.attachEvent('onclick', foo)
    } else {
        el.onclick = foo;
    }
    function foo() {
        ...
        return false;
    }

    See the following for further details
    http://www.quirksmode.org/js/events_early.html
    http://www.quirksmode.org/js/events_tradmod.html
    http://www.quirksmode.org/js/events_advanced.html
    Programming Group Advisor
    Reference: JavaScript, Quirksmode Validate: HTML Validation, JSLint
    Car is to Carpet as Java is to JavaScript

  3. #3
    SitePoint Evangelist winterheat's Avatar
    Join Date
    Aug 2007
    Posts
    508
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    thanks... what is the reason that we don't use

    <a href="javascript:foo()">Next Image</a>

    ? is it that some browser won't support it, or is it just because we want to move the javascript away from the HTML code? (unobtrusive JS)?

  4. #4
    Unobtrusively zen silver trophybronze trophy
    paul_wilkins's Avatar
    Join Date
    Jan 2007
    Location
    Christchurch, New Zealand
    Posts
    14,729
    Mentioned
    104 Post(s)
    Tagged
    4 Thread(s)
    If the the javascript pseudo protocol can't find the function, it creates a new page and shows the contents there instead. So it is possible to have

    Code html4strict:
    <a href="javascript:<h1>Site branding</h1><p>Thanks for registering</p>">...</a>

    The javascript pseudo protocol isn't used for a variety of reasons. As well as the reasons already mentioned, the pseudo protocol doesn't work when there is no javascript, resulting in a do-nothing link which is a very poor experience for the consumer.

    There is only one justabiable use for the javascript pseudo protocol and that is as a bookmarlet, allowing you to run scripts from the browsers bookmark/favourites area.

    The href for a link must point to a valid URL. The pseudo protocol definately isn't one, and while it can be argued that "#" is valid, it's a bad idea. All other links to "#" will be marked as being visited when one of the others is selected, and linking to the top of the page in that way is a bad idea to begin with.

    The href should link to a relevant location. If it's linking to a script that shows the next image, the href should point to that next image. Even if it's normally not used, someone without javascript will then be able to use the page without too much trouble.

    One of the side-benefits of having a valid link in the href is that scripts can easily make use of it.

    Code html4strict:
    <a id="nextImage" href="image.jpg">next image</a>

    Code javascript:
    document.getElementById('nextImage').onclick = nextImage;
    function nextImage() {
        var image = this.href;
        // do stuff with image
        this.href = getNextImage();
    }
    Programming Group Advisor
    Reference: JavaScript, Quirksmode Validate: HTML Validation, JSLint
    Car is to Carpet as Java is to JavaScript

  5. #5
    SitePoint Evangelist winterheat's Avatar
    Join Date
    Aug 2007
    Posts
    508
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    so you mean when the user turned off javascript support on the browser, then href="javascript:foo()" will not work and is bad experience for the user...

    so what if the page is very AJAX dependent... which is to load some content using AJAX into a div... and that the whole page won't really work without javascript (the development team decided not to support users who have javascript turned off).

    also if the link is to use AJAX to load some content into a div, then there is really no "target URL" for the href to point to. In that case, is there a better alternative to using href="#" ?

  6. #6
    Programming Since 1978 silver trophybronze trophy felgall's Avatar
    Join Date
    Sep 2005
    Location
    Sydney, NSW, Australia
    Posts
    16,875
    Mentioned
    25 Post(s)
    Tagged
    1 Thread(s)
    1. Never use href="javascript:anything" as that does not trigger as an event handler and with no code to process it will not work properly.

    2. Never use href="#" unless the intention is to link to the top of the page.

    The best option for if you don't want the code to actually link to anything if JavaScript is disabled would be

    Code:
    <span style="color:#00f;cursor:pointer;text-decoration:underline" onclick="whatever">text to click on to run whatever</span>
    That way there isn't a broken link when JavaScript is didabled and it still looks and works the same way when JavaScript is enabled.

    Of course the styles would go in the stylesheet and be referenced by class.
    Stephen J Chapman

    javascriptexample.net, Book Reviews, follow me on Twitter
    HTML Help, CSS Help, JavaScript Help, PHP/mySQL Help, blog
    <input name="html5" type="text" required pattern="^$">

  7. #7
    Unobtrusively zen silver trophybronze trophy
    paul_wilkins's Avatar
    Join Date
    Jan 2007
    Location
    Christchurch, New Zealand
    Posts
    14,729
    Mentioned
    104 Post(s)
    Tagged
    4 Thread(s)
    Then you could go all the way and use progressive enhancement so that nobody gets what they should be expecting.

    Code css:
    #gallery ul {
    	margin: 0;
    	padding: 0;
    	text-decoration: none;
    }
    .pseudo-link {
    	color: #00f;
    	cursor: pointer;
    	text-decoration: underline;
    }

    Code html4strict:
    <html>
    <head>
    <link rel="stylesheet" type="text/css" href="css/style.css">
    </head>
    <body>
    <div id="gallery">
    	<ul>
    		<li><img src="image.jpg"></li>
    		<li><img src="image.jpg"></li>
    		<li><img src="image.jpg"></li>
    </div>
    <script src="js/script.js"></script>
    </body>
    </html>

    Code javascript:
    var el = document.getElementById('gallery'),
    	els = el.getElementsByTagName('img'),
    	i;
    for (i = 0; i < els.length; i += 1) {
        addFaveLink(els[i]);
    }
    function addFaveLink(el) {
    	var els = document.createDocumentFragment();
    	els.appendChild(document.createTextNode(' '));
    	span = document.createElement('span');
    	span.className = 'pseudo-link';
    	span.appendChild(document.createTextNode('+fave'));
    	span.onclick = addFave;
    	els.appendChild(span);
    	if (el.nextSibling) {
    		el.parentNode.insertBefore(els, el.nextSibling);
    	} else {
    		el.parentNode.appendChild(els);
    	}
    }
    function addFave() {
        ...
    }
    Programming Group Advisor
    Reference: JavaScript, Quirksmode Validate: HTML Validation, JSLint
    Car is to Carpet as Java is to JavaScript

  8. #8
    SitePoint Author silver trophybronze trophy

    Join Date
    Nov 2004
    Location
    Ankh-Morpork
    Posts
    12,158
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by felgall View Post
    The best option for if you don't want the code to actually link to anything if JavaScript is disabled would be

    Code:
    <span style="color:#00f;cursor:pointer;text-decoration:underline" onclick="whatever">text to click on to run whatever</span>
    Except that this will be totally inaccessible if you don't use a mouse or other pointing device. Most browsers only let you navigate to links and form controls via the keyboard.

    The appropriate way to include something that only works if JavaScript is supported and enabled is to create that element with JavaScript. Use unobtrusive scripting to create a link or button and register an event listener for it. No JavaScript = no non-functional element = no user frustration.
    Birnam wood is come to Dunsinane

  9. #9
    Function Curry'er JimmyP's Avatar
    Join Date
    Aug 2007
    Location
    Brighton, UK
    Posts
    2,006
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Just as an FYI:

    The JavaScript pseudo class is also very useful for quickly performing actions to a page from the bookmarks panel. (Paul mentioned this already)

    Say I wanted to have a button which would immediately hide all images within a page (maybe if you were at work and looking at naughty sites ), I could create a bookmark and assign it the following location:

    Code JavaScript:
    javascript:function toggle(i) {i.style.visibility=(i.style.visibility==='hidden') ? 'visible' : 'hidden';}var i=document.getElementsByTagName('img'),l=i.length;while(l--){toggle(i[l]);}

    Or if I wanted to highlight all links on the page:

    Code JavaScript:
    javascript:function hl(i) {i.style.backgroundColor='yellow';i.style.color='black'}var a=document.getElementsByTagName('a'),l=a.length;while(l--){hl(a[l]);}

    You can test these out by copying them into the address bar.
    James Padolsey
    末末末末末末末末末末末末末末末末末末末
    Awesome JavaScript Zoomer (demo here)
    'Ajaxy' - Ajax integration solution (demo here)


Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •