views:

208

answers:

5

Is there a reason why I should call a Javascript method as follows:

onClick="Javascript:MyMethod();"

or can I just call it like this:

onClick="MyMethod();"

Is there any difference?

+14  A: 

The value of an onclick attribute is code, not a URI, so this is correct (though not the only way you might do it, see tangent #1 below):

onClick="MyMethod();"

This is incorrect but largely harmless:

onClick="Javascript:MyMethod();"

Sometimes people think the latter is using the javascript protocol, like on links, but it isn't. It's doing something else entirely. The language of the code in the onclick attribute is defined at page level (and defaults to JavaScript), and so what you're actually doing is declaring a label in your JavaScript code, and then calling MyMethod. JavaScript has labels (see tangent #2 below), though they're not used much.

The onclick attribute is totally different from the href attribute on links:

<a href="javascript:MyMethod();">

There, since we're putting code where a URI is expected, we have to specify a URI using the javascript protocol, so the browser knows what we're doing. javascript is a protocol (like http or mailto) that Brendan Eich (creator of JavaScript) was clever enough to define and register (and implement) very, very early on so it's well-supported.

Finally: Best to make onclick all lower case, not mixed case, although it only really matters if you use XHTML.


Tangent #1

Perhaps a bit off-topic, but: Using the HTML attributes for hooking up handlers is perfectly valid and works well cross-browser, but it intermixes your JavaScript event hookup with your HTML. Some people see that as a good thing, others belong to the "unobtrusive JavaScript" side and think you should hook everything up later. What you do is up to you. The unobtrusive approach is particularly useful when your HTML designers and your JavaScript coders are not the same people (as happens frequently on large teams).

The unobtrusive approach basically says: Don't use the HTML attributes for this, do it later from script. So instead of

<ul id='tabset'>
    <li onclick="setTab(1);">Tab 1</li>
    <li onclick="setTab(2);">Tab 2</li>
    <li onclick="setTab(3);">Tab 3</li>
</ul>

you might have this HTML:

<ul id='tabset'>
    <li>Tab 1</li>
    <li>Tab 2</li>
    <li>Tab 3</li>
</ul>

combined with this JavaScript:

function hookUpTabs() {
    var tabset, tab;
    tabset = document.getElementById('tabset');
    for (tab = tabset.firstChild; tab; tab = tab.nextSibling) {
        if (tab.tagName == "LI") {
            tab.onclick = setTab; // Hooks up handler, but there are better ways
        }
    }
}

...where setTab uses context to figure out which tab was clicked and act accordingly, and hookUpTabs is called as soon as the DOM is ready. Note that where we're setting up the click handler, we're assigning a function reference, not a string, to the onclick on the tab div.

I wouldn't actually use onclick in the above, I'd use DOM2 handlers via the addEventListener (standard) / attachEvent (Microsoft) functions. But I didn't want to get into standard vs. Microsoft stuff. And you don't either, if you start doing unobtrusive JavaScript, use a library to handle that stuff for you (jQuery, Prototype, Closure, whatever).


Tangent #2

Another mildly off-topic tangent: So, what are these JavaScript labels then? Details in the spec as always, but here's an example of using labels with a directed break statement in a loop:

var innerIndex, outerIndex;

// Label the beginning of the outer loop with the (creative) label "outerloop"
outerloop: for (outerIndex = 0; outerIndex < 10; ++outerIndex) {

    for (innerIndex = 0; innerIndex < 50; ++innerIndex) {

        if (innerIndex > 3) {
            break; // Non-directed break, breaks inner loop
        }

        if (innerIndex > 2 && outerIndex > 1) {
            // Directed break, telling the code that we want to break
            // out of the inner loop *and* the outer loop both.
            break outerloop;
        }

        display(outerIndex + ":" + innerIndex);
    }
}

Live Example

T.J. Crowder
Intersting, because asp.net would do this:href="javascript:__doPostBack('ctl00$MainContent$grdTemplate$ctl16$lnkComment','')"
Krummelz
asp.net does a lot of things.
Stephen
Are those correct or incorrect? Why would Microsoft make asp.net generate code that way, if its not correct?
Krummelz
@Krummelz: Microsoft is not quite known for adhering to standards.
elusive
@Krummelz - href="javascript:MyMethod();" is correct. onclick="javascript:MyMethod();" is not.
Joel Etherton
@Krummetz: `href` is different from `onclick`. As it happens, I was drawing the distinction as you commented, so the updated answer should help. :-)
T.J. Crowder
Careful! You need to differentiate between the `href` and `onclick` attributes. `href` needs the `javascript:` pseudo-protocol to know that that is JavaScript and not an URL. `onclick` doesn't need it, because onclick can only contain JavaScript and not an URL.
RoToRa
Note that the ASP.NET example uses a javascript: pseudo-URL in the HREF attribute of a link, not in its onclick event. That works, but it's a serious no-no from an accessibility perspective; the way to do it with a link would be <a href="" onclick="__doPostBack(...); return false;"> -- and the preference there would be to have the href actually point to another page that can handle the noscript case.
Stan Rogers
`href=""` is not the same as `onClick=""`. `href=` is a link, and then you need the `javascript:` to tell it that you want to execute javascript and not go to a url, whereas `onClick=` is an event handler that presumes javascript.
ormuriauga
@elusive: True enough, but they are with that `href`.
T.J. Crowder
wow, thanks guys! awesome explanations :) stackoverflow ftw!
Krummelz
@T.J. Crowder: You're right ;)
elusive
Umm... How about just `onclick = MyMethod;`?
Ates Goral
@Ates: Hey, why stop there, let's go down the `addEventListener`/`attachEvent` route! :-) No, seriously, agreed. Most (not all) of the time, best to attach handlers separately and avoid mixing your JavaScript and HTML.
T.J. Crowder
Technically Eich didn't register the `javascript:` URL scheme, he just went ahead and used it (originally as `mocha:`). Indeed, Netscape 2 predated the RFC2717 process. Oh, how I wish he had never invented the foul disease of `javascript:` URLs. The endless, needless usability and security disaster they've caused...
bobince
@bobince: Nonsense! Without `javascript` URLs, we wouldn't have bookmarklets! Re registration, tomato, tomatoh, he created them. :-)
T.J. Crowder
+2  A: 

onclick already presumes you're executing Javascript, so there's no need for a javascript: pseudo-url.

Marc B
+1  A: 

AFAIK, you are defining a jump label with the name Javascript here. You shouldn't do that. This makes no difference to the call. This is the way to go:

onClick="MyMethod();"
elusive
+2  A: 

The difference is that the first one is wrong.

The first one just happens to work because someidentifier: happens to be the syntax for a label in JavaScript, but since there is no need for a label there, there is no point of adding it.

RoToRa
can please somebody elaborate on someidentifier: usage when exactly we be using it.what exactly happens when javascript: is called
sushil bharwani
@sushil bharwani: `javascript:` is not called. It defines a jump label in javascript and is completely unnecessary in this case.
elusive
@sushil: It's a JavaScript label. It's hardly used. See for example: https://developer.mozilla.org/en/JavaScript/Reference/Statements/label
RoToRa
@sushil: In addition to the excellent reference RoToRa gave above, I've also done a small explanation and example in [my answer](http://stackoverflow.com/questions/3761167/proper-way-of-calling-a-javascript-method/3761175#3761175).
T.J. Crowder
+10  A: 

I was goaded into giving you an alternative. Inline Javascript makes your HTML difficult to follow. Seperating your javascript (logic) from your HTML (presentation) is the way to go. in jQuery it would be something like this:

$(function() {
    $('#the-element').click(function() {
        MyMethod();
    });
});

Put that in your head or external script file. Preferably where your MyMethod is defined. Now your element is clean, and all of your method calls are located in the same place, rather than spread out through the HTML.

Stephen
+1 for being unobstrusive.
elusive