Sick of while?
Experienced programmers who have trudged through the past five pages
will probably have frequently asked themselves the questions:
"Hmm. We've learnt about while as a way of repetitively
doing things, but what about other ways? Most languages have constructs
such as for .. next and so on! In addition, although if
.. then .. else makes sense, what about the C++ switch
statement as a mechanism for flow control? "
JavaScript has many constructs for 'flow control'. We've deliberately avoided them up to now, because,
quite frankly, they are unnecessary (although occasionally convenient).
We've really tried to keep to what is necessary, and they are not. We'd
go so far as to say that they often impair the readability of code!
But for the record, here they are:
-
for (initialisation ;
condition ;
update )
{ /* things to do go here */ };
The idea with for is that a variable is initialised,
and then repetitively altered until a condition fails to be met.
A sort of while with attitude.
We might for example say:
for ( i = 1; i < 10; i ++ ) { /* do stuff here */ };
Note that we could increment i before we tested
it by saying "++ i"
instead of "i ++" - try out the two
to see the difference!
-
do { /* things to do go here */ }
while (condition);
This is similar to while, but always does something before
the first test is made. Totally unnecessary, and only available
in JavaScript 1.2 and above! Avoid it.
-
break
Allows you to break out of a loop and bash on with the
code after the loop. Occasionally useful. Avoid using a label
with the break statement, as this silly wrinkle is only available
in JavaScript 1.2 and above.
-
continue
Allows you to jump to the end of the loop and then
continue with the loop. Once in a blue moon this may be
more useful than confusing to the reader.
-
with ( something )
{ /* things to do */ };
with has a specific reason for its existence -
it's for lazy people. If you don't want to retype an object
name again and again, use with and the object name
is automatically put in where needed (within the scope of
the curly braces). Superficially, this might make things
easier to read .. but watch out!
-
for ( variable in object )
{ /* things to do */ };
At last .. something that might be useful. This rather
cunning construct allows you to make up a name (variable
in the above prototype), and then the script magically sets
variable to each property of the object. You
can work through all the properties of an object without
knowing their names!
-
switch ( expression )
{ case value0 :
/* statements for case of value0 */
break
case value1 :
/* and so on .. */
default:
/* default statements if no other case taken */
};
switch would have been great if it had been introduced
in JavaScript 1.0 - unfortunately it only appeared in 1.2.
Note that a common error with this statement
is to leave out a break statement (did you notice that
we did so above?), often with surprising
results. Just ask the Java and C++ programmers!
Sick of while? Well, stick with while!
Cookies
Ever signed onto a password-protected website and then noticed that every time you visit
the site again, you automatically get signed on (provided you're on the
same computer)? Such behaviour shows both the convenience of cookies, and
the potential they give the website-designer for keeping tabs on customers.
At present though, cookies are more useful than irritating.
Web-pages were initially designed to be stateless - that is,
every time you visited the page, you got the same thing. Unfortunately,
this sort of behaviour is not very human-friendly, especially if, as in
the above example, you have to repeatedly sign onto a web-site. The
correct solution is to avoid such paranoid practices on your site, but
cookies have other uses.
They work as follows - when a cookie is set, then this
information is remembered on your computer inside a file called
cookies.txt - the 'cookie jar'. (Find it on your machine)! The next time you
request that page, the browser sees the cookie, and sends the information
contained in the cookie together with a request for the web-page.
The CGI script on the other end then says either "aha. Joe bloggs is
visiting my porno site again", or does something useful with the information
such as logging you on automatically. Clearly the "thought police" aspect
of cookies depends on what information you have provided to the CGI
at the other end - it only knows you are Joe Bloggs if you've provided
the information; but it might label you as "user 1234" or whatever.
There is of course the potential for multiple servers on the other side
to pool their cookie-based information. Note that you can turn off cookies
in your browser (or, if the worst comes to the worst, replace the
cookies.txt file on your machine with a directory called cookies.txt
which will prevent the browser from making a file of that name). Most
of the time, it's probably more reasonable just to leave the bloody
thing enabled. One can be too paranoid.
How does a CGI program set a cookie?
This is easily done by sending a particular header to your browser. The
header is called a Set-Cookie header, and sets several attributes of
the cookie, including:
- a name=value pair;
- an expiry date;
- a path;
- a domain;
- a 'secure' option.
ONLY the name=value pair is mandatory - it contains the data being
stored. If the expiry date is not specified, the cookie becomes
stale and is thrown away when you finish your browser session; the
path attribute forces the browser to associate the cookie with
requests for all page requests in any subdirectory of the
path. The domain attribute is even more cunning - any host within that
domain gets the cookie (but not top level domains like .com or
.org - the cookie makers were at least wise enough to prevent this
sort of widespread dissemination of information). The secure
option when set will only allow the cookie information to be sent
over a secure communication channel.
Can I duplicate the above using JavaScript?
We wouldn't be talking about cookies if you couldn't. The syntax is
straightforward - we set a cookie using:
document.cookie=CookieDescriptor;
where CookieDescriptor must be in the appropriate format.
An example of the format is:
document.cookie="myname=fred; expires=Friday, 13-Oct-2000 12:00:01 GMT"
Similarly, we can retrieve a cookie by just allocating a variable
to the value:
thatName=document.cookie
You may want to browse through the source of this page to see
exactly how we did the above! See how we set the expiry time for
five minutes into the future - if you quickly get out of your browser
and then restart it, the cookie will persist; otherwise, wait a bit,
exit, restart and .. it's gone.
Clearly it's silly to clutter up somebody's cookie jar with cookies
they'll never use - set cookies and their expiry times with caution.
What can't we put into a cookie?
Try typing various things into the above cookie container, to test its
limits! You'll find that (surprisingly) a variety of punctuation is
acceptable. See how multiple values are appended to the cookie, separated
by semicolons.
If you leave the name field blank, something is still added, but this
is unwise - it would be best to ensure that you always set cookies
using the name=value format.
(What about the maximum number and sizes
of cookies? Most browsers should allow at least 300 cookies, with
a maximum of 20 properties, and 4K for each!)
How do I pull out the expiry time?
The simple answer is "You can't" - we don't know of any method you
can use to interrogate JavaScript for the time at which a cookie expires.
The obvious solution is
to set a separate variable equal to the expiry time, and then you
can just pull this out of the cookie!
Finding out if the system supports cookies
There is no smart way to do this, apart from simply writing an
arbitrary cookie, and then checking that the value you wrote is
available by fetching the cookie value!
Animation and Layers
Web pages now have a vast potential for animated images. Unfortunately,
due to incompatibilities between MSIE, and Netscape Navigator versions
4 and 6, it's a mess. To efficiently move images about the screen, you
need to understand layers in their various (incompatible) incarnations.
1. Layers in Netscape
Netscape decided to define several new tags (including <LAYER>,
<ILAYER> as well as their closures and the <NOLAYER> and
</NOLAYER> tags), starting from NN 4.0. In order to make
their new navigator, NN 6.x fully compliant with the W3C DOM specifications,
they have now abandoned these tags!! If you want to read about how
they (used to) work, with a demonstration, then click here.
2. Layers in MS Internet Explorer!
Try our MSIE example
If you went to the bother of trying the Netscape layer example, you
would have seen that it was actually rather straightforward. More's
the pity that Netscape themselves (egged on by the W3C) have abandoned
this simple approach.
Look at the plethora of features available if you click on the
"Try me" button in our MSIE example. Contrast this
with the Netscape version (view it in a Netscape
browser).
A universal page
Try this page - it should work with MSIE 4.x(+)
and with Netscape 4.x. As soon as we've had a good look at NN 6.x, we'll
update it to work there too! See how NN also understands the <div id="xx"
style="yy"> tag, which we used in this common page, but access through
JavaScript is different from that of MSIE. {This section still needs a lot
more work}.
Which version of javascript?
Newer versions of JavaScript seem to be appearing all the time.
Avoid writing code that is incompatible with older versions if
you possibly can. In other words, unless you absolutely MUST have
a certain feature, write code that will work on the lowest version - 1.0 !
Let's look at the major versions:
- Version 1.0 - This is found in Netscape version 2. It's really
not too bad, although if you try and feed it 1.1 or especially
1.2 code, it may crash horribly. The Microsoft 'equivalent'
is perhaps the JScript 1.x of Internet Explorer 3.x, which
as we've said should be avoided.
- Version 1.1 - Now we're cooking. This is the version of
JavaScript found in Netscape Navigator 3.x.
- Version 1.2 is the JavaScript version for
Netscape version 4.0x (excluding version 4.06). Netscape Navigator
versions 4.5x and up support at least JavaScript 1.3.
The Microsoft JScript version corresponding to JavaScript 1.2 is
JScript 3.x (Microsoft seems to have jumped from JScript 1 to 3 to
5).
Both JavaScript 1.3 and JScript 3.x are compliant with ECMA-262;
note that JavaScript 1.2 is almost compliant (but not totally,
as it has some trouble with unicode and with platform-specific
date-handling). Internet Explorer version 5.x sports JScript 5.x;
in addition you can upgrade your JScript version for IE without
upgrading the explorer - so for example, you can run JScript 5.x
with IE 3.0 !
Basically if you've got JavaScript 1.2 or JScript 3.x, you're
more-or-less OK. For full 'EcmaScript' compatibility, you need
JavaScript 1.3(+) or JScript 3.0(+). Note that if you have
a Mac, there is a host of buggy versions of Internet Explorer that
you should avoid like poison (Now why should this be?)
Here's a cute way of checking the JavaScript version:
Checking the JavaScript version
|
<script language='JavaScript'>
<!--
JSver = "1.0";
//-->
</script>
<script language='JavaScript1.1'>
<!--
JSver = "1.1";
//-->
</script>
<script language='JavaScript1.2'>
<!--
JSver = "1.2";
//-->
</script>
<script language='JavaScript'>
<!--
alert("I see you're using JavaScript Version " + JSver);
//-->
</script>
|
The variable is only updated to 1.1 or 1.2 if the corresponding
scripts are run, and they are only run if the version matches!
Pretty, isn't it?
Turning to a different issue, the WWW Consortium has made recommendations
for the JavaScript DOM. Level zero is met by NN 3.x and IE 3.x , and level 1, and more
recently (November 2000) level 2, are now recommendations.