<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.