Welcome back. Now that your brain has re-acclimated to the semicolons and curly braces of the JavaScript world, it’s time to learn something useful and exciting.
We’ll spend this lesson sampling those tasty treats known as cookies – the little bits of information you can leave on the computers of people who visit your site. Cookies allow you to give your pages a personal touch. For instance, with a cookie you can “remember” people’s names and serve up a warm greeting every time they re-visit. You can also remember user preferences – if a visitor generally comes in on a slow connection, a cookie lets you know to automatically serve them minimal graphics.
Cookies can be very useful — and sometimes scary:When I buy airplane tickets online, the service I use remembers not only my name, but also where I live and my seating preferences. It even knows who I traveled with last and asks if that person will be joining me on my next flight. There’s a fine line between useful and invasive.
As long as you use them responsibly and effectively (and don’t freak anyone out with Big Brother knowledge), cookies can be extremely handy for all sorts of reasons. So I’m going to show you how they work. But before we get our hands all doughy, we should cover two JavaScript topics:fancy string handling and associative arrays.
Contents
- Fancy String Handling
- indexOf
- charAt
- String Exercise 1
- Substring
- The Split Method
- Associative Arrays
- Example of an Associative Array
- Cookie Introduction
- More About Cookies
- Setting Cookies
- Reading Cookies
- Complicated Cookie Reading
- Reading and Writing Multiple Cookies
- More About Cookies
- Cookie Path and Domain
- Lesson 2 Review
|
Fancy String Handling
Why do you have to learn about fancy string handling before getting into the joyous world of cookies? Well, it turns out that cookies are strings. To store visitor information, you have to first build a special cookie string. And then to read the information when the visitor returns, you have to decode the cookie string. To create and interpret these strings, you have to know your way around JavaScript’s string library.
You should be pretty familiar with strings, since we’ve been working with them all along, but for a refresher, take a look at
Part I, Day 2 to see how to make an ordinary string bold:
1 | var normal_monkey = "I am a monkey!<br>" ; |
3 | document.writeln( "Normal monkey " + normal_monkey); |
5 | var bold_monkey = normal_monkey.bold(); |
7 | document.writeln( "Bold monkey " + bold_monkey); |
The statement:
1 | var bold_monkey = normal_monkey.bold(); |
Is the same as the statement:
1 | var bold_monkey = "<b>" + normal_monkey + "</b>" ; |
The first version just looks neater. One of the many methods of the string object is bold
, and it’s sort of silly. Less silly are the methods indexOf, charAt, substring,
and split
, which actually get inside strings and see what they’re made of. Let’s look at indexOf
first.
indexOf
The indexOf
finds the location of a set of characters inside a string and tells you where the substring starts. If the string doesn’t contain the substring, indexOf
returns “-1.” Here are some examples:
var the_word = "monkey";
- Let’s start with the word “monkey.”
var location_of_m = the_word.indexOf("m");
- The
location_of_m
will be “0,” because that’s the starting position of a string.
var location_of_o = the_word.indexOf("o");
- The
location_of_o
will be “1.”
var location_of_key = the_word.indexOf("key");
location_of_key
is “3″ because the substring “key” starts with “k,” which is position three in the word “monkey.”
var location_of_y = the_word.indexOf("y");
- The
location_of_y
is “5.”
var cheeky = the_word.indexOf("q");
- The
cheeky
is “-1″ because there’s no letter “q” in the word “monkey.”
A more realistic use of indexOf
is:
01 | var the_email = prompt( "What's your email address?" , "" ); |
03 | var the_at_is_at = the_email.indexOf( "@" ); |
05 | if (the_at_is_at == -1) |
09 | alert("You loser, email addresses must |
11 | have @ signs in them."); |
This little scrap of code asks users for their email address, and then checks to see if it’s a valid address. If the address doesn’t contain an @ sign, it can’t be valid. Enter indexOf
, which checks for “@” in the string.
charAt
The charAt
finds out what letter is at a certain position inside a string. Here it is in action:
1 | var the_word = "monkey" ; |
3 | var the_first_letter = the_word.charAt(0); |
5 | var the_second_letter = the_word.charAt(1); |
7 | var the_last_letter = the_word.charAt(the_word.length-1); |
After this, the_first_letter
is “m,” the_second_letter
is “o,” and the_last_letter
is “y.” Note that you can find out how many letters are in a word using the length property of the string. In this case, the_word
is “monkey,” so the_word.length
is “6.” Don’t forget that the first character of a string is at position “0″ (as in charAt(0)
), so the last letter will be in position length-1
, which is why the last line features the_word.length-1
.
Before going over substring
and split
, let’s do an exercise with charAt
and indexOf
.
String Exercise 1
Your task is to write a script that will determine whether the last letter of a word is a vowel or a consonant. You can do it in a clever way, using both indexOf
and charAt
. Of course you could do it in a much less clever way without indexOf
, but remember:the clever monkey gets the golden banana.
Here’s an example of
it working. When you’ve finished the exercise, or nearly died trying, learn how it’s done or double-check your work against
my solution. Or, if you’re so pleased with your solution that you don’t want to sully your mind with mine, feel free to carry on with the string-a-thon.
Substring
The substring
is just like charAt
except it can grab entire substrings from a word, not just letters. Here’s the format:
1 | var the_substring = the_string.substring(from, to); |
“From” refers to the position of the first character of the substring, and “to” is, strangely enough, one greater than the last position of the substring. Using this weird method to mark the beginning and end of the substring makes it so that “to” minus “from” gives you the length of the substring:
1 | var the_string = "monkey" ; |
3 | var clergy = the_string.substring(0,4); |
5 | var tool = the_string.substring(3,6); |
After this batch of code runs, “clergy” will equal “monk”; “tool” will equal “key.”
The substring
is often used with indexOf
to break apart strings. For example, you could pull out the domain name of a given URL:
01 | var the_url = prompt( "What's the URL?" , "" ); |
03 | var lead_slashes = the_url.indexOf( "//" ); |
05 | var domain_start = lead_slashes + 2; |
07 | var without_resource = the_url.substring(domain_start, the_url.length); |
09 | var next_slash = without_resource.indexOf( "/" ); |
11 | var domain = without_resource.substring(0, next_slash); |
Which means if you enter “http://aitu-im240.blogspot.com/2014/10/advanced-javascript-tutorial-lesson-2.html,” the domain will equal “http://aitu-im240.blogspot.com.” Try the
domain grabber to see it work. If this code seems like kind of a drag to you, don’t worry. After I break it down line by line, I’ll show you how to make things much simpler using the
split
method. First, however, the analysis.
The basic tactic we’re using here is to isolate everything between the first double slash and the next slash. Here’s how we do it:
var the_url = prompt("What's the URL?","");
- This just asks the user for a URL. Let’s say they enter “http://aitu-im240.blogspot.com/2014/10/advanced-javascript-tutorial-lesson-2.html.”
var lead_slashes = the_url.indexOf("//");
- This locates the first two slashes. In the case of our example URL,
lead_slashes
equals “5″ because the two slashes start at position five. What’s that? You wonder, “if the string is a URL, it always starts with http://
, so why don’t we just assume, oh so cleverly, that the two slashes start at position five instead of messing around with indexOf
?” The thing is, you never know what people will do at the prompt. They might enter “the URL I want is http://www.blah.com/.” Or they might accidentally put a space before the URL. Or maybe they enter a URL that’s on a secure server, making it something like “https://www.whatever.com/.”One of the hardest things about programming is anticipating all possible cases and then coming up with a way to handle them. Ask people to drop information into an open text field, and you never quite know what you’ll get. So we can’t just assume that the two slashes are at positions five and six. Instead, we need to use the indexOf
method to determine exactly where the two slashes start.
var domain_start = lead_slashes + 2;
- This calculates the location of the first letter of the domain. Because there are two slashes, the first letter of the domain will be two positions over from the slashes.
var without_resource = the_url.substring(domain_start, the_string.length);
- This grabs everything from the beginning of the domain name (which we determined in the previous line of code) and the end of the string. So, using the current example,
without_resource
is “www.webmonkey.com/javascript/index.html.”
var next_slash = without_resource.indexOf("/");
- This figures out the position of the next slash in the string. Everything between the beginning of the string and this slash is domain name. In this case, the next slash is in position seventeen.
var domain = without_resource.substring(0, next_slash);
- This final step grabs everything from the beginning of the string to the position of the next slash. In the current case, that makes domain equal to “www.webmonkey.com.”
And there you have it. Yes, it’s a pain. If it makes you feel any better, string handling is a pain in almost all languages. JavaScript 1.2, which was introduced with Netscape 4.0, takes some strides toward making string handling easier. But it’s still a pain.
The whole process can be handled quite a bit more easily with the split
method.
The Split Method
When you have a list of things separated by a delimiter, you generally use split
. Say you have a list of names separated by commas – split
takes that list and puts each of the names into an array. For example:
01 | var my_friends = "trixie,moxie,sven,guido,hermes" ; |
03 | var friend_array = my_friends.split( "," ); |
05 | for ( var loop=0; loop < friend_array.length; loop++) |
09 | document.writeln(friend_array[loop] + " is my friend.<br>" ); |
This breaks the string my_friends
into an array of five elements. (Happily, JavaScript creates the array for you automatically, so you don’t have to use new Array()
to create it yourself).
After breaking the string into an array, we loop through it, writing out each friend’s name. If arrays or loops are unfamiliar to you, check out
Part I, Day 4 for an explanation.
We can use split
to make the earlier domain grabber easier to code:
1 | var the_url = prompt( "What's the URL?" , "" ); |
3 | var first_split = the_url.split( "//" ); |
5 | var without_resource = first_split[1]; |
7 | var second_split = without_resource.split( "/" ); |
9 | var domain = second_split[0]; |
This is much more attractive, and easier to understand, right? Here’s the breakdown:
var the_url = prompt("What's the URL?","");
- As before, this requests a URL (let’s go with “http://www.webmonkey.com/javascript/index.html” again).
var first_split = the_url.split("//");
- This splits the string into two pieces:
first_split[0]
is “http:” and first_split[1]
is “www.webmonkey.com/javascript/index.html.”
var without_resource = first_split[1];
- This just grabs the second element in the array, so now
without_resource
is “www.webmonkey.com/javascript/index.html.”
var second_split = without_resource.split("/");
- This breaks
without_resource
into three pieces:www.webmonkey.com
, javascript
, and index.html
. See how useful split
is?
var domain = second_split[0];
- Now all we have to do is grab the first element of the
second_split
array. And voila! We’re done.
That might seem to be a lot of work at first, but you’ll get used to it pretty fast. I personally love split
– it’s a special coding treat.
Now that you’ve learned all the fancy string handling routines for cookies, take a breather – you’ve just digested quite a mouthful of information. Go for a little stroll. Have a snack. OK? Then it’s time to learn one last thing before sallying forth into cookie country:associative arrays.
Associative Arrays
If you’ve done any JavaScript programming, you’re probably familiar with arrays, which let you store lists of items and also give you access to the images, forms, and form elements of your HTML pages. In
Part I, Day 4, I showed you how to create and manipulate arrays that are indexed by number. For example:
1 | var an_array = new Array( "hickory" , "dickory" ); |
3 | var element_one = an_array[0]; |
5 | var element_two = an_array[1]; |
This creates a new array and initializes it with two strings. The first element of the array is accessed using its index number, “0.” The second element, element 1 of the array, is accessible with an_array[1]
. You can add to an array by assigning something to a specific index of the array:in the example above, I made the third element of the array equal to “doc.” Now the array contains “hickory, dickory, doc.”
Associative arrays are just like the array above, except rather than using numbers to index elements in the array, you use words.
1 | var phone_book = new Array(); |
3 | phone_book[ "sleepy" ] = "(203) 555-1234" ; |
5 | phone_book[ "happy" ] = "(203) 555-2345" ; |
This creates sort of a phone book. Access the phone number for “happy” by writing:
1 | var happy_number = phone_book[ "happy" ]; |
Try out the working phone book example on the next page to see how an associative array might work (and get a major refresher on the use of JavaScript with forms at the same time).
Example of an Associative Array
This example is a bit involved, so let’s go through it slowly. First let’s look at the phone book itself. The phone book, which is defined in the header ( phone_book
) and has seven entries, looks like this:
01 | var phone_book = new Array(); |
03 | phone_book[ "happy" ] = "(203) 555-1234" ; |
05 | phone_book[ "sleepy" ] = "(203) 555-2345" ; |
07 | phone_book[ "sneezy" ] = "(203) 555-4321" ; |
09 | phone_book[ "sleazy" ] = "(203) 555-3245" ; |
11 | phone_book[ "sneery" ] = "(203) 555-3213" ; |
13 | phone_book[ "bleary" ] = "(203) 555-2365" ; |
15 | phone_book[ "tweaked" ] = "(203) 555-1664" ; |
The key to each entry is the name of the dwarf, and the value of each entry is that dwarfs’s phone number. When we want to get a phone number for our favorite dwarf, say “Sneezy,” we write this:
1 | var the_number = phone_book[ "sneezy" ]; |
Now let’s look at the form:
09 | "displayNumber(phone_book,this.options[selectedIndex].value);" > |
11 | <option value= "happy" >Happy |
13 | <option value= "sleepy" >Sleepy |
15 | <option value= "sneezy" >Sneezy |
17 | <option value= "sleazy" >Sleazy |
19 | <option value= "sneary" >Sneery |
21 | <option value= "bleary" >Bleary |
23 | <option value= "tweaked" >Tweaked |
33 | <input type= "text" name= "number_box" value= "" > |
Note that the form and the elements inside the form have names. This allows us to read and write to the form elements. Also, take a look at the
onChange
handler in the select tag. This says that when the
select
is changed, it calls the function
displayNumber
, which is defined up in the header. If I use the pulldown to select “sneezy,” the expression
this.options[selectedIndex].value
returns “sneezy.” If you need a refresher on this kind of form madness, check out
Part I, Day 5. Once we’ve figured out what the user has selected, we jump to the
displayNumber
function, which looks like this:
1 | function displayNumber(phone_book, entry) |
5 | var the_number = phone_book[entry]; |
7 | window.document.the_form.number_box.value = the_number; |
It takes two parameters – a phone book and a name – to make this function work. The first line of the function,
1 | var the_number = phone_book[entry]; |
looks the name up in the phone book, and the next line,
1 | window.document.the_form.number_box.value = the_number; |
puts that number into the form element called number_box
.
And there you have it. As you can see, associative arrays are a good way to link one string to another. They’re useful for linking names to phone numbers, to passwords, to birthdays, and all kinds of things. A few lessons from now, I’ll introduce another useful trick you can do with associative arrays, so don’t cast them into the facts-best-forgotten pit quite yet.
And now, if you’re ready for it, let’s sink our teeth into cookies!
No comments:
Post a Comment