Apparent namespace clash

S

Safalra

The problem below is obviously some sort of namespace clash, but I don't
understand exactly why - can anyone explain? Take the following simple
Javascript code:

<script type="text/javascript">
function scrollLeft(){ alert('scrollLeft') };
function scrollLeft2(){ alert('scrollLeft2') };
scrollLeft();
scrollLeft2();
</script>

This pops up two alert boxes saying 'scrollLeft' and 'scrollLeft2' as you
would expect. However, if you then add a couple of buttons calling these
functions:

<form><div>
<input type="button" value="scrollLeft" onClick="scrollLeft();">
<input type="button" value="scrollLeft2" onClick="scrollLeft2();">
</div></form>

....then the button calling scrollLeft doesn't work - Firefox's Javascript
Console says 'ScrollLeft is not a function'. What I don't understand is
that if scrollLeft is already defined somewhere automatically (the only
other code on the page is the minimal necessary HTML), why did the call to
the function inside the <script> element work?
 
R

Richard Cornford

Safalra said:
The problem below is obviously some sort of namespace clash, but
I don't understand exactly why - can anyone explain? Take the
following simple Javascript code:

<script type="text/javascript">
function scrollLeft(){ alert('scrollLeft') };
function scrollLeft2(){ alert('scrollLeft2') };
scrollLeft();
scrollLeft2();
</script>

This pops up two alert boxes saying 'scrollLeft' and 'scrollLeft2' as you
would expect. However, if you then add a couple of buttons calling these
functions:

<form><div>
<input type="button" value="scrollLeft" onClick="scrollLeft();">
<input type="button" value="scrollLeft2" onClick="scrollLeft2();">
</div></form>

...then the button calling scrollLeft doesn't work - Firefox's Javascript
Console says 'ScrollLeft is not a function'.

The two onclick event handling functions created by Firefox have
'augmented' scope chains. There is no standardisation in the scope
chain augmentation that may happen with the functions generated from
intrinsic event attributes in the HTML, but Mozilla/Gecko browser
(since about Netscape 6 / Mozilla 0.9) have added all the elements on a
path through the DOM from the element in question to the root of the
DOM to the event handler's scope chain. As a result the FORM element is
on the scope chain for the event handler and so when an Identifier is
resolved inside the generated function each object on the scope chain
is examined (in turn) to see if it has a property with the
corresponding name and if one is found it is the value of that property
(on the first object that has a property with that name) that because
the value of the Identifier.

The FORM is on the scope chain and in HTML DOMs FORM elements
traditionally have named properties corresponding with named form
controls (as used in traditional (but non-standard) 'shortcut' property
accessors). Thus the Identifier - scrollLeft - is resolved as whatever
value is referred to by the ' scrollLeft' property of the FORM element,
and that property is a reference to the named INPUT element, which is
not a function and so errors when called.

Although IE browsers use a different scope chain augmentation strategy
with their event handlers a similar result will be found in that
browser.
What I don't understand is that if scrollLeft is already defined
somewhere automatically (the only other code on the page is
the minimal necessary HTML), why did the call to the function
inside the <script> element work?

The calls to - scrollLeft - and - scrollLeft2 - inside the SCRIPT
element are executed in the global execution context, where the scope
chain only includes the global object. As both of the declared global
functions are properties of the global object their identifiers are
resolved as expected in that context.

Richard.
 
D

Dr John Stockton

JRS: In article <[email protected]>, dated Wed,
12 Jul 2006 14:58:49 remote, seen in Safalra
...then the button calling scrollLeft doesn't work - Firefox's Javascript
Console says 'ScrollLeft is not a function'. What I don't understand

Richard has given a specific answer.

In general, though, in any such case where the last quoted clause
applies, ISTM worth repeating with all relevant identifiers changed to
ones which are extremely unlikely to clash in any manner whatsoever with
each other or any extant global.

Identifiers __000 to __999 should AFAIK fulfil those conditions,
unless already used by the programmer.
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,906
Latest member
SkinfixSkintag

Latest Threads

Top