A tag: href vs. onClick

Discussion in 'Javascript' started by usenet@vikas.mailshell.com, Oct 23, 2005.

  1. Guest

    See

    <ul>
    <li><a name="link1" onClick="alert(this.name);return false;"
    href="#">Link1</a></li>
    <li><a name="link2" href="javascript:alert(this);">Link2</a></li>
    <li>Item 3</li>
    </ul>

    Clicking on the first list item gives me "link1" because "this" refers
    to the A node so this.name returns the value of the name attribute of
    that node.

    But in the second link, "this" seems to refer to the window node!

    Why is this? Why does the meaning of "this" change so drastically when
    used in a href=javascript: vs. a onClick=

    Thanks
     
    , Oct 23, 2005
    #1
    1. Advertising

  2. Randy Webb Guest

    said the following on 10/22/2005 11:00 PM:
    > See
    >
    > <ul>
    > <li><a name="link1" onClick="alert(this.name);return false;"
    > href="#">Link1</a></li>
    > <li><a name="link2" href="javascript:alert(this);">Link2</a></li>
    > <li>Item 3</li>
    > </ul>
    >
    > Clicking on the first list item gives me "link1" because "this" refers
    > to the A node so this.name returns the value of the name attribute of
    > that node.
    >
    > But in the second link, "this" seems to refer to the window node!


    Yeppers. Because the javascript: pseudo-protocol is executed in the
    global context.

    > Why is this? Why does the meaning of "this" change so drastically when
    > used in a href=javascript: vs. a onClick=


    this doesn't change, what changes is the context in which it is executed.

    Don't use javascript:, use the onclick and you don't have that problem.

    --
    Randy
    comp.lang.javascript FAQ - http://jibbering.com/faq & newsgroup weekly
     
    Randy Webb, Oct 23, 2005
    #2
    1. Advertising

  3. Lee Guest

    said:
    >
    >See
    >
    ><ul>
    ><li><a name="link1" onClick="alert(this.name);return false;"
    > href="#">Link1</a></li>
    ><li><a name="link2" href="javascript:alert(this);">Link2</a></li>
    ><li>Item 3</li>
    ></ul>
    >
    >Clicking on the first list item gives me "link1" because "this" refers
    >to the A node so this.name returns the value of the name attribute of
    >that node.
    >
    >But in the second link, "this" seems to refer to the window node!
    >
    >Why is this? Why does the meaning of "this" change so drastically when
    >used in a href=javascript: vs. a onClick


    The onclick handler is a method of the link. The "javascript:"
    pseudo-protocol is a mechanism for loading new content into the page.
    For example:

    <a href="javascript:(new Date()).toLocaleString()">What time is it?</a>

    Using it to execute arbitrary functions is a perversion of its intended
    function. Since it is loading new content into the page, the page
    (ie, the window) is its execution context.
     
    Lee, Oct 23, 2005
    #3
  4. VK Guest

    > <a name="link2" href="javascript:alert(this);">Link2</a>

    > <a href="javascript:(new Date()).toLocaleString()">What time is it?</a>


    I'd just like to point again that you *never ever* should use
    javascript:someFunction() syntacs. The only place and time for it is
    when you're replacing the current page by a new HTML page generated by
    someFunction.

    To call JavaScript from javascript: while staying on the same page you
    have to use void() wrapper:
    javascript:void(whateverYouWant)
    Otherwise it's going to be a gross misuse of javascript:
    pseudo-protocol.
     
    VK, Oct 23, 2005
    #4
  5. wrote:

    > Why is this? Why does the meaning of "this" change so drastically when
    > used in a href=javascript: vs. a onClick=


    Because it relies on `javascript:', a proprietary, almost undocumented URI
    scheme. Implementors cannot be blamed in any way if they do not implement
    code attached there to be run in the context of the element object that
    fired the event but instead in the global context (and so have pointing
    `this' to the Global Object instead which happens to be the current
    `window' object in most/all HTML DOMs).


    HTH

    PointedEars
     
    Thomas 'PointedEars' Lahn, Oct 23, 2005
    #5
  6. VK wrote:
    >> <a name="link2" href="javascript:alert(this);">Link2</a>

    >
    >> <a href="javascript:(new Date()).toLocaleString()">What
    >> time is it?</a>

    >
    > I'd just like to point again that you *never ever* should use
    > javascript:someFunction() syntacs. The only place and time
    > for it is when you're replacing the current page by a new
    > HTML page generated by someFunction.
    >
    > To call JavaScript from javascript: while staying on the same
    > page you have to use void() wrapper:
    > javascript:void(whateverYouWant)
    > Otherwise it's going to be a gross misuse of javascript:
    > pseudo-protocol.


    The void operator produces an expression that results in the value -
    Undefined -. It takes the value of its operand and throws it away, and
    evaluated to Undefined instead. Whenever a function call is that
    operand, and that function itself returns - Undefined -, using that
    function call as an operand to - void - is redundant and pointless.

    If the value of the expression was such that not applying the - void -
    operator would result in the replacement of the current document, and
    the replacement of the current document was not desired, then applying
    the - void - operator would make sense. But suggesting that all function
    calls used in a javascript pseudo-protocol context should be made into
    operands of - void - is taking an action that has a known rational, an
    purpose under _some_ circumstances, and promoting it to the status of a
    mystical incantation, to be chanted in the face of all javascript HREFs.
    This does not represent a contribution to computer programming.

    Richard.
     
    Richard Cornford, Oct 23, 2005
    #6
  7. wrote:
    > <ul>
    > <li><a name="link1" onClick="alert(this.name);return false;"
    > href="#">Link1</a></li>
    > <li><a name="link2" href="javascript:alert(this);">Link2</a></li>
    > <li>Item 3</li>
    > </ul>
    >
    > Clicking on the first list item gives me "link1" because "this"
    > refers to the A node so this.name returns the value of the name
    > attribute of that node.
    >
    > But in the second link, "this" seems to refer to the window node!
    >
    > Why is this? Why does the meaning of "this" change so drastically
    > when used in a href=javascript: vs. a onClick=


    The only circumstances under which the - this - keyword refers to
    anything other than the global object (which is also the window object
    in web browsers) is when a function is *executed* as a method of an
    object.

    A web browser will take he string provided as the value of an onclick
    attribute and use it as the body of a function that it creates
    internally and attaches to the - onclick - property of the corresponding
    element in the DOM. When the corresponding event occurs this internally
    generated function is called as a method of the element in question, and
    so the - this - reference has the normal handling for methods and refers
    to the element.

    Code executed as a result of acting upon a javascript pseudo-protocol
    HREF is not executed as a function at all. This can be demonstrated by
    executing - href="javascript:return false;" -, which produces a syntax
    error along the lines of 'return outside of function'.

    The javascript pseudo-protocol is unspecified and nearly undocumented so
    its actual behaviour is uncertain, implementation depended and extremely
    variable. In the past it has been possible to extract clues about the
    behaviour of specific implementations, for example, in IE 4 triggering:-

    <a href="javascript:'cc';" target="_blank">
    Javascript Pseudo-protocol test</a>

    - had the effect of opening a new window (because of target="_blank")
    and viewing the source in that new window showed:-

    <HTML>
    <SCRIPT LANGUAGE=javascript>
    var __w='cc';
    if(__w!=null)document.write(__w);
    </SCRIPT>
    </HTML>

    - and so provided an insight into how IE 4 implemented the javascript
    pseudo-protocol. Later IE versions removed the ability to see this code
    by viewing the source of such a pop-up.

    You will observe that the code following the - javascript:- in the HREF
    (the string literal 'cc' in this case) is inserted into a code block in
    a context where it represents the right hand side of an assignment
    expression that is executed as an ExpressionStatement in a global
    context. The result of the evaluation of that expression (as assigned to
    the global variable - __w -) is then tested for type-converted
    equivalence with - null - and, when _not_ equivalent, passed through the
    document.write method (with all of its implications for the destruction
    of any "current" document).

    It has also been observed that executing a javascript pseudo-protocol
    HREF in some browsers triggers a 'state' change. Apparently a result of
    'navigation' associated with the expected outcome of triggering any
    link's HREF (and the resulting anticipated replacement of the page's
    contents). The most evident symptom of this 'state' change is provided
    by Windows IE, where triggering a javascript pseudo-protocol HREF
    immediately terminates the animation of animated GIF images. However,
    many other unexpected symptoms are suspected to be a result of this
    'state' change, and so it can only be reasonably recommended that
    javascript pseudo-protocol HREFs never be used unless their expected
    action is to replace the current page (or page contents) in the browser.

    Richard.
     
    Richard Cornford, Oct 23, 2005
    #7
  8. VA Guest

    Thanks for everyone's input.

    To summarize: When the javascript: pseudo-protocol is used in the HREF
    attribute of the A tag, it executes in the global context and so "this"
    refers to the window object. When it is used in the onClick event
    handler, the "this" refers to the A node.

    I was surprised to get so much "never ever use the href=javascript:
    URI, it is baaad, evil, etc" comments. Come on guys, leave the
    "language purists" stuff aside...In 2005, is there any modern
    website/web app that really runs at all if I turn off Javascript.
    Client-side scripting and DOM manipulation is so ingrained in the web
    development world that it can safely be taken for granted. So, to me,
    href="javascript:something()" and onClick="something();return false;"
    are really equivalent for all practical intents and purposes. Of
    course, If you need to use "this" in your function and need it to refer
    to the A node, use the event handler variant, simple.

    Thanks
     
    VA, Oct 23, 2005
    #8
  9. VA Guest

    Richard Cornford wrote:
    > It has also been observed that executing a javascript pseudo-protocol
    > HREF in some browsers triggers a 'state' change. Apparently a result of
    > 'navigation' associated with the expected outcome of triggering any
    > link's HREF (and the resulting anticipated replacement of the page's
    > contents).


    I am not sure I understand. The expected outcome of triggering any
    link's HREF is not always to replace the page's content. Even if we
    leave Javascript out of this, how about <a href="#anchor">? Following
    that HREF just navigates to a different section of the currently loaded
    document. So does this also trigger the "state change" you mention?

    Thanks
     
    VA, Oct 23, 2005
    #9
  10. Guest

    VA wrote:

    > To summarize: When the javascript: pseudo-protocol is used in the HREF
    > attribute of the A tag, it executes in the global context and so "this"
    > refers to the window object.


    Maybe, maybe not. That's the problem with proprietary features.

    > When it is used in the onClick event handler, the "this" refers to the
    > A node.


    Most certainly.

    > I was surprised to get so much "never ever use the href=javascript:
    > URI, it is baaad, evil, etc" comments. Come on guys, leave the
    > "language purists" stuff aside...


    Some things work reliably, others don't. This has nothing to do with
    purity, it has to do with how to get the job done and maintained
    efficiently. `href="javascript:..."' is considered a Bad Thing for
    good reasons. One reason is that it is not reliable (as you have
    experienced) and another one that it does not only not degrade
    gracefully itself, using it in place of a proper `http:' URI prevents
    the link from degrading gracefully.

    > In 2005, is there any modern website/web app that really runs at
    > all if I turn off Javascript.


    Oh yes, there are plenty. And the more plain ignorance towards the user
    such as displayed by you is taken away from the minds of Web designers, the
    more they become Web authors who write for their readers, the less services
    will no longer not degrade gracefully, so allowing hopefully *all* users an
    adequate experience of the presented content, whether they use a desktop
    PC, a notebook, a PDA, a mobile phone, a Braille line, a reading machine,
    a printer or any other device.

    > Client-side scripting and DOM manipulation is so ingrained in the web
    > development world that it can safely be taken for granted.


    Definitely not. But you are still missing the point anyway.

    > So, to me, href="javascript:something()" and onClick="something();return
    > false;" are really equivalent for all practical intents and purposes.


    They are not.

    > Of course, If you need to use "this" in your function and need it
    > to refer to the A node, use the event handler variant, simple.


    No, the two features are following completely different approaches.
    And while the DOM event model continues to evolve, `javascript:' is
    supported merely for reasons of backwards compatibility.


    PointedEars
     
    , Oct 23, 2005
    #10
  11. VA wrote:
    > Richard Cornford wrote:
    >> It has also been observed that executing a javascript
    >> pseudo-protocol HREF in some browsers triggers a 'state'
    >> change. Apparently a result of 'navigation' associated
    >> with the expected outcome of triggering any link's HREF
    >> (and the resulting anticipated replacement of the page's
    >> contents).

    >
    > I am not sure I understand.


    The situation is as easily demonstrated as explained. find yourself an
    animated GIF, preferably one that shows constant change so that it is
    instantly apparent when it stops being animated and place a reference to
    it in the IMG element's SRC in the following HTML:-

    <html>
    <body>
    <img src="anAnimated.gif">
    <br>
    <a href="javascript:void 0;">javascript:void 0;</a>
    <br>
    <a href="http://bogus.example.com/">http://bogus.example.com/</a>
    </body>
    </html>

    - and load the result into a Windows IE 6. Then clink the javascript
    pseudo-protocol link. The odds are good that the animation will stop
    animating at precisely that point. If you then re-load the page the
    animation should start again, and if you subsequently click the
    bogus.example.com link you should (while the domain is failing to
    resolve) have an opportunity to observe that the animation of the GIF
    also stops. This demonstrates that the current document undergoes a
    'state' change when a javascript pseudo-protocol HREF is activated that
    is apparently similar to a 'state' change that accompanies requests to
    navigate.

    > The expected outcome of triggering any link's HREF
    > is not always to replace the page's content. Even if we
    > leave Javascript out of this, how about <a href="#anchor">?
    > Following that HREF just navigates to a different section
    > of the currently loaded document. So does this also trigger
    > the "state change" you mention?


    It is not useful to observe that a browser may recognise that the
    activation of some HREFs do not represent navigation, and so do not
    necessarily induce an equivalent 'state' change, so long as javascript:
    HREFs can be demonstrated to be treated as navigation in some browsers.
    We have a real, demonstrable, condition that applies to versions of a
    web browsers that cannot be ignored in commercial web authoring. And we
    have good reason to believe that the undesirable consequences of the
    execution of javascrip pseudo-protocol HREFs go well beyond the visually
    apparent symptoms exposed by animated GIFs.

    We can speculate about the nature and extent of this 'state' change and
    suffer the consequences of being overly-optimistic, or plain wrong, or
    we can notice that there are no remaining circumstances in the DOM where
    the execution of a javascript pseudo protocol HREF cannot be completely
    avoided with the use of an appropriately default-action cancelling
    intrinsic event handler, and so avoid ever having to provoke the
    condition or deal with the consequences. Thus, for this reason, in
    addition to many others, best practice is to never use a javascript
    pseudo-protocol HREF that is not intended to completely replace the
    current page.

    Richard.
     
    Richard Cornford, Oct 23, 2005
    #11
  12. VA Guest

    wrote:
    > Some things work reliably, others don't. This has nothing to do with


    Just to clarify...other than the demonstrated example of "this" meaning
    different things, what exactly does *not* work when href="javascript:"
    is used?

    > experienced) and another one that it does not only not degrade
    > gracefully itself, using it in place of a proper `http:' URI prevents
    > the link from degrading gracefully.


    But what if I (as the web designer) have nothing to degrade to? In
    other words, the functionality that my website/app provides can only be
    delivered using Javascript?

    So are you suggesting that I do something like

    href="sorry.html" onClick=...
    where sorry.html informs the user that Javascript is required for
    proper functionality?

    > Oh yes, there are plenty. And the more plain ignorance towards the user


    Can you please point me to some? I am honestly curious to see some
    commercial, useful websites providing some product/service on the
    public Internet that are implemented without using Javascript.

    > such as displayed by you is taken away from the minds of Web designers, the

    [...]
    > adequate experience of the presented content, whether they use a desktop
    > PC, a notebook, a PDA, a mobile phone, a Braille line, a reading machine,
    > a printer or any other device.


    I think your jab on my "ignorance" is not warranted. Presenting content
    for all various output devices you mention above is the domain of the
    presentation layer, which, I am sure you agree is CSS. CSS has plenty
    of features for displaying output device-appropriate content.
    (off-topic for this forum, so we'll leave it at that, shall we?).

    What we are talking about in this thread is functionality ("what
    happens when I click on this link?"), not presentation ("how does this
    page look?").

    > No, the two features are following completely different approaches.
    > And while the DOM event model continues to evolve, `javascript:' is
    > supported merely for reasons of backwards compatibility.


    I dont understand this. Backward compatibility comes into the picture
    when Version x+1 of some technology supercedes some feature in Version
    x. Until all the users of that technology "catch up", Version x+1 also
    supports the usage of that feaure just as if Version x were running.

    In this case, the A tag and its HREF attribute was present from Day 1.
    Along comes Javascript and its onSomething event handlers. Older
    browser that did NOT implement Javascript and its event handlers
    therefore "ignored" the unknown (to them) onClick attribute of the A
    tag.

    But if they didnt understand/implement Javascript, what use is
    providing a href="javasript:function()" feature? Those browsers cant
    interpret/run the "function()" anyway! So whats the point? In other
    words, who is the intended audience of this "backward compatibility"
    feature?

    Thanks
     
    VA, Oct 23, 2005
    #12
  13. VA Guest

    Richard: Thank you for that wonderfully eloquent refutation. I am duly
    enlightened. Thanks again.
     
    VA, Oct 23, 2005
    #13
  14. Randy Webb Guest

    VA said the following on 10/23/2005 4:28 PM:
    > wrote:
    >
    >>Some things work reliably, others don't. This has nothing to do with

    >
    >
    > Just to clarify...other than the demonstrated example of "this" meaning
    > different things, what exactly does *not* work when href="javascript:"
    > is used?


    Any link in my cell phone browser for starters.

    >
    >>experienced) and another one that it does not only not degrade
    >>gracefully itself, using it in place of a proper `http:' URI prevents
    >>the link from degrading gracefully.

    >
    >
    > But what if I (as the web designer) have nothing to degrade to? In
    > other words, the functionality that my website/app provides can only be
    > delivered using Javascript?
    >
    > So are you suggesting that I do something like
    >
    > href="sorry.html" onClick=...
    > where sorry.html informs the user that Javascript is required for
    > proper functionality?


    Yes. That is preferable to getting a blank page and no indication of
    why. The browser in my cell phone is a non-JS browser so at least some
    kind of indication of why it isn't working is a great help.

    > But if they didnt understand/implement Javascript, what use is
    > providing a href="javasript:function()" feature? Those browsers cant
    > interpret/run the "function()" anyway! So whats the point? In other
    > words, who is the intended audience of this "backward compatibility"
    > feature?


    See above.

    --
    Randy
    comp.lang.javascript FAQ - http://jibbering.com/faq & newsgroup weekly
     
    Randy Webb, Oct 24, 2005
    #14
  15. VA Guest

    Randy Webb wrote:
    > > But if they didnt understand/implement Javascript, what use is
    > > providing a href="javasript:function()" feature? Those browsers cant
    > > interpret/run the "function()" anyway! So whats the point? In other
    > > words, who is the intended audience of this "backward compatibility"
    > > feature?

    >
    > See above.


    I dont understand. See above for what? My question was "if the client
    cannot understand Javascript (thus causing it to ignore the onClick),
    then what use is providing a href=javascript:?" That wont be understood
    either.
     
    VA, Oct 24, 2005
    #15
  16. Randy Webb Guest

    VA said the following on 10/23/2005 11:35 PM:

    > Randy Webb wrote:
    >
    >>>But if they didnt understand/implement Javascript, what use is
    >>>providing a href="javasript:function()" feature? Those browsers cant
    >>>interpret/run the "function()" anyway! So whats the point? In other
    >>>words, who is the intended audience of this "backward compatibility"
    >>>feature?

    >>
    >>See above.

    >
    >
    > I dont understand. See above for what? My question was "if the client
    > cannot understand Javascript (thus causing it to ignore the onClick),
    > then what use is providing a href=javascript:?" That wont be understood
    > either.
    >


    My bad, I mis-read the question.


    I do not believe that handling href="javascript: was in the beginnings
    of the browsers. It was an afterthought (a very poorly thought out one)
    when scripting came along. And it was introduced before the onclick
    event handler as a way to allow a link to activate a script. Now, there
    is no need for that use. As for why the browser vendors leave the
    support in, who knows. Probably the same reason they leave eval support in.

    But even if my intentions were to replace the entire contents of the
    page via script, I still wouldn't use a href="javascript: construct to
    do it.

    --
    Randy
    comp.lang.javascript FAQ - http://jibbering.com/faq & newsgroup weekly
     
    Randy Webb, Oct 24, 2005
    #16
  17. VA Guest

    Randy Webb wrote:
    > support in, who knows. Probably the same reason they leave eval support in.


    Hm? Forgive the newbie question, but you seem to be saying "eval" is
    not necessary in the Javascript language? So whats the alternative?

    Thanks
     
    VA, Oct 24, 2005
    #17
  18. Dag Sunde Guest

    "VA" <> wrote in message
    news:...
    > Randy Webb wrote:
    >> support in, who knows. Probably the same reason they leave eval support
    >> in.

    >
    > Hm? Forgive the newbie question, but you seem to be saying "eval" is
    > not necessary in the Javascript language? So whats the alternative?
    >


    Turn the question around:

    Name a few scenarios where you feel eval() *is* neccessary, and we will
    try to show you why its not...

    --
    Dag.
     
    Dag Sunde, Oct 24, 2005
    #18
  19. VK Guest

    > I was surprised to get so much "never
    > ever use the href=javascript: URI, it is baaad, evil, etc" comments.


    Who said that?!? Not me.
    javascript: p-protocol is a great thing. You just need to know how it
    works and enjoy ever after.

    1) javascript:someFunction() means: "execute someFunction and replace
    current page by content from someFunction's return value". Thusly if
    someFunction returns null, you'll end up with a blank page with the
    proud word "null" written in the top left corner.

    2) javascript:void(someFunction()) means: "where will be no new content
    provided, just stay where you are; and by the way execute
    someFunction".

    Despite what some people says, void() operand *doesn't return* neither
    null, nor undefined. As its name suggests it does not return any values
    whatsoever. This is how it works in Java also (there this idea has been
    taken from).
    Yes if you try to assign
    var foo = void(something);
    then you'll get undefined. But it's the same "pseudo-value" as in case:

    var arr = new Array(1,2,3);
    var foo = arr[1000]; // the same undefined as with void()

    JavaScript is just too samplified and user-friendly to bother you (and
    itself) with fine details. So it just gives you undefined every time
    you're trying to go beyond the scope of the program or to get return
    value from something that doesn't have it by definition or do something
    equally bizarre ;-)
     
    VK, Oct 24, 2005
    #19
  20. Randy Webb Guest

    VA said the following on 10/24/2005 6:49 AM:
    > Randy Webb wrote:
    >
    >>support in, who knows. Probably the same reason they leave eval support in.

    >
    >
    > Hm? Forgive the newbie question, but you seem to be saying "eval" is
    > not necessary in the Javascript language? So whats the alternative?


    http://jibbering.com/faq/#FAQ4_40

    --
    Randy
    comp.lang.javascript FAQ - http://jibbering.com/faq & newsgroup weekly
     
    Randy Webb, Oct 24, 2005
    #20
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. shruds
    Replies:
    1
    Views:
    893
    John C. Bollinger
    Jan 27, 2006
  2. CRON
    Replies:
    24
    Views:
    202,829
    Adrienne Boswell
    Jun 20, 2006
  3. Soren Vejrum
    Replies:
    4
    Views:
    682
    Lasse Reichstein Nielsen
    Jul 5, 2003
  4. Replies:
    2
    Views:
    534
  5. Vincent van Beveren

    BASE HREF and A HREF="#" onclick="..."

    Vincent van Beveren, Jul 6, 2006, in forum: Javascript
    Replies:
    2
    Views:
    355
    Vincent van Beveren
    Jul 6, 2006
Loading...

Share This Page