Chapter 10 In this chapter you looked at some common mistakes in JavaScript code, debugging code using theMicrosoft script debugger, and ways of handling errors using the try...catchclau
Trang 1Well, that would work, but it would also replace the a in “walked,” which you don’t want You want to replace the letter a, but only where it’s a word on its own and not inside another word So when does a
letter become a word? The answer is when it’s between two word boundaries The word boundary isrepresented by the regular expression special character \b, so the regular expression becomes this:var myRegExp = /\ba\b/gi;
The giat the end ensures a global, case-insensitive search
Now, with your regular expression created, you can use it in the replace()method’s first parameter.myString = myString.replace(myRegExp,”the”);
<script language=”JavaScript” type=”text/javascript”>
var myRegExp = /(sugar )?candy|choc(olate|oholic)?/gi;
var myString = “Mmm, I love chocolate, I’m a chocoholic “ +
“I love candy too, sweet, sugar candy”;
For this example, pretend you’re creating script for a board on a dieting site where text relating to candy
is barred and will be replaced with references to a much healthier option, salad
The barred words are:
Trang 2Start with the two basic words, so to match choc or candy, use this:
candy|choc
Next, add the matching for sugar candy Since the sugarbit is optional, you group it by placing it inparentheses and adding the question mark after it This means “Match the group zero times or onetime.”
(sugar )?candy|chocFinally you need to add the optional olateand oholicend bits You add these as a group after the
“choc” word and again make the group optional You can match either of the endings in the group byusing the |character
(sugar )?candy|choc(olate|oholic)?/giFinally, you declare it as follows:
var myRegExp = /(sugar )?candy|choc(olate|oholic)?/giThe giat the end means that the regular expression will find and replace words on a global, case-insensitive basis
So, to sum up:
/(sugar )?candy|choc(olate|oholic)?/gireads as:
Either match zero or one occurrences of “sugar” followed by “candy.” Or alternatively match “choc” followed by either one or zero occurrences of “olate” or match “choc” followed by zero or one occurrence of “oholic.”
Finally, the following:
myString = myString.replace(myRegExp,”salad”);
replaces the offending words with “salad” and sets myStringto the new clean version:
“Mmm, I love salad, I’m a salad I love salad too, sweet, salad.”
Chapter 9
In this chapter you looked in more detail at the Dateobject, particularly with respect to world time andlocal time You also looked at how to create timers to trigger code on a web page
Trang 3Question 1
Create a web page with an advertisement image at the top When the page loads, select a random imagefor that advertisement Every four seconds, make the image change to a different one, making sure a dif-ferent advertisement is selected until all the advertisement images have been seen
Solution
<html>
<head>
<script language=”JavaScript” type=”text/javascript”>
var imagesSelected = new Array(false,false,false);
for (imageIndex = 0; imageIndex < noOfImages; imageIndex++){
imagesSelected[imageIndex] = false;
}totalImagesSelected = 0;
}var selectedImage = Math.floor(Math.random() * noOfImages) + 1;
while (imagesSelected[selectedImage - 1] == true)
{
selectedImage = Math.floor(Math.random() * noOfImages) + 1;
}totalImagesSelected++;
Trang 4Save this as ch09_q1.htm.This solution is based on the example in the chapter, Adverts.htm, in which you displayed threeimages at set intervals, one after the other The first difference is that you select a random image eachtime, rather than the images in sequence Secondly, you make sure you don’t select the same image twice
in one sequence by having an array, imagesSelected, with each element of that array being trueorfalsedepending on whether the image has been selected before Once you’ve shown each image, youreset the array and start the sequence of selecting images randomly again
The final difference between this solution and the example in the chapter is that you set the timer goingcontinuously with setInterval() So until the user moves to another page, your random display ofimages will continue
<script language=”JavaScript” type=”text/javascript”>
var days = new Array();
var form = document.form1;
var date = parseInt(form.txtDate.value)var year = parseInt(form.txtYear.value)
if (isNaN(date) || isNaN(year)){
alert(“Please enter a valid whole number”);
}else{
if (date < 1 || date > 31){
alert(“Day of the month must be between 1 and 31”);
}else
Trang 5{userDate = date + “ “;
userDate = userDate +
form.selMonth.options[form.selMonth.selectedIndex].value;
userDate = userDate + “ “ + year;
var dateThen = new Date(userDate);
alert(days[dateThen.getDay()]);
}}}
<option selected value=”Jan”>Jan</option>
<option selected value=”Feb”>Feb</option>
<option selected value=”Mar”>Mar</option>
<option selected value=”Apr”>Apr</option>
<option selected value=”May”>May</option>
<option selected value=”Jun”>Jun</option>
<option selected value=”Jul”>Jul</option>
<option selected value=”Aug”>Aug</option>
<option selected value=”Sept”>Sept</option>
<option selected value=”Oct”>Oct</option>
<option selected value=”Nov”>Nov</option>
<option selected value=”Dec”>Dec</option>
Trang 6whether invalid dates are entered (for example, the 31st of February) You might want to try this as anadditional exercise.
Hint: To get the last day of the month, get the first day of the next month and then subtract one.
Chapter 10
In this chapter you looked at some common mistakes in JavaScript code, debugging code using theMicrosoft script debugger, and ways of handling errors using the try catchclause and the throwstatement
for (counter = 1; counter < 12; counter++)You want your loop to go from 1to 12inclusive Your counter < 12statement will be trueup to andincluding 11but will be falsewhen the counter reaches 12; hence 12gets left off To correct this, youcould change your code to the following:
for (counter = 1; counter <= 12; counter++)
var formValid = true;
var elementCount = 0;
while(elementCount =< theForm.length){
Trang 7if (theForm.elements[elementcount].type == “text”){
if (theForm.elements[elementCount].value() = “”)alert(“Please complete all form elements”)theForm.elements[elementCount].focus;
formValid = false;
break;
}}return formValid;
}
</script>
<form name=form1 onsubmit=”return checkForm(document.form1)”>
<input type=”text” ID=text1 name=text1>
if (theForm.elements[elementCount].type == “text”){
if (theForm.elements[elementCount].value == “”){
alert(“Please complete all form elements”)theForm.elements[elementCount].focus();
formValid = false;
break;
Trang 8}return formValid;
}
</script>
<form name=”form1” onsubmit=”return checkForm(document.form1)”>
<input type=”text” id=”text1” name=”text1”>
Let’s look at each error in turn
The first error is a logic error
while(elementCount =< theForm.length)Arrays start at 0so the first Formobject is at index array 0, the second at 1, and so on The last Formobject has an index value of 4 However, theForm.lengthwill return 5because there are five elements
in the form So the whileloop will continue until elementCountis less than or equal to 5, but as thelast element has an index of 4, this is one past the limit You should write either this:
while(elementCount < theForm.length)
or this:
while(elementCount <= theForm.length - 1)Either is fine, though the first is shorter
You come to your second error in the following line:
if (theForm.elements[elementcount].type == “text”)
Trang 9On a quick glance it looks fine, but it’s JavaScript’s strictness on case sensitivity that has caused yourdownfall The variable name is elementCount, not elementcountwith a lowercase c So this line
should read as follows:
if (theForm.elements[elementCount].type == “text”)
The next line with an error is this:
if (theForm.elements[elementCount].value() = “”)
This has two errors First, valueis a property and not a method, so there is no need for parentheses after
it Second, you have the all-time classic error of one equals sign instead of two Remember that oneequals sign means “Make it equal to,” and two equals signs mean “Check if it is equal to.” So with thechanges, the line is:
if (theForm.elements[elementCount].value == “”)
The next error is your failure to put your block of ifcode in curly braces Even though JavaScript won’tthrow an error since the syntax is fine, the logic is not so fine, and you won’t get the results you expect.With the braces, the ifstatement should be as follows:
This line should be in your whileloop, otherwise elementCountwill never go above 0and the whileloop’s condition will always be true, resulting in the loop continuing forever: a classic infinite loop
Chapter 11
In this chapter you looked at storing small amounts of information, called cookies, on the user’s puter and using that information to customize your web site for the user
Trang 10var cookieValue = document.cookie;
var cookieStartsAt = cookieValue.indexOf(“ “ + cookieName + “=”);
if (cookieStartsAt == -1){
cookieStartsAt = cookieValue.indexOf(cookieName + “=”);
}
if (cookieStartsAt == -1){
cookieValue = null;
}else{cookieStartsAt = cookieValue.indexOf(“=”, cookieStartsAt) + 1;
var cookieEndsAt = cookieValue.indexOf(“;”, cookieStartsAt);
if (cookieEndsAt == -1){
cookieEndsAt = cookieValue.length;
}cookieValue = unescape(cookieValue.substring(cookieStartsAt,cookieEndsAt));
}return cookieValue;
}function setCookie(cookieName,cookieValue, cookiePath, cookieExpires){
cookieValue = escape(cookieValue);
if (cookieExpires == “”){
var nowDate = new Date();
nowDate.setMonth(nowDate.getMonth() + 6);
cookieExpires = nowDate.toGMTString();
}
if (cookiePath != “”){
cookiePath = “;Path=” + cookiePath;
}
Trang 11document.cookie = cookieName + “=” + cookieValue + “;Expires=” + cookieExpires + cookiePath;
}
var pageViewCount = getCookieValue(“pageViewCount”);
var pageFirstVisited = getCookieValue(“pageFirstVisited”);
var pageHTML = “You’ve visited this page “ + pageViewCount;
pageHTML = pageHTML + “ times since “ + pageFirstVisited;
We discussed the cookie functions in Chapter 11, so let’s turn straight to the new code
In the first two lines we get two cookies and store them in variables The first cookie holds the number ofvisits, the second the date the page was first visited
var pageViewCount = getCookieValue(“pageViewCount”);
var pageFirstVisited = getCookieValue(“pageFirstVisited”);
If the pageViewCountcookie does not exist, it’s either because the cookie expired (remember that we arecounting visits for the last month) or because the user has never visited our site before Either way weneed to set the pageViewCountto 1and store the date the page was first visited plus one month in thepageFirstVisitedvariable We’ll need this value later when we want to set the expiresvalue for thepageViewCountcookie we create because there is no way of using code to find out an existing cookie’sexpiration date
if (pageViewCount == null)
{
pageViewCount = 1;
Trang 12pageFirstVisited = new Date();
pageFirstVisited.setMonth(pageFirstVisited.getMonth() + 1)pageFirstVisited = pageFirstVisited.toGMTString();
setCookie(“pageFirstVisited”,pageFirstVisited,””,””)}
In the elsestatement we increase the value of pageViewCount.else
{pageViewCount = Math.floor(pageViewCount) + 1;
}
We then set the cookie keeping track of the number of page visits by the user
setCookie(“pageViewCount”,pageViewCount,””,””)Finally, we write out the number of page visits and the date since the counter was reset
var pageHTML = “You’ve visited this page “ + pageViewCount;
pageHTML = pageHTML + “ times since “ + pageFirstVisited;
var cookieValue = document.cookie;
var cookieStartsAt = cookieValue.indexOf(“ “ + cookieName + “=”);
if (cookieStartsAt == -1){
cookieStartsAt = cookieValue.indexOf(cookieName + “=”);
}
if (cookieStartsAt == -1){
cookieValue = null;
}else{cookieStartsAt = cookieValue.indexOf(“=”, cookieStartsAt) + 1;
Trang 13var cookieEndsAt = cookieValue.indexOf(“;”, cookieStartsAt);
if (cookieEndsAt == -1){
cookieEndsAt = cookieValue.length;
}cookieValue = unescape(cookieValue.substring(cookieStartsAt, cookieEndsAt));}
var nowDate = new Date();
nowDate.setMonth(nowDate.getMonth() + 6);
cookieExpires = nowDate.toGMTString();
}
if (cookiePath != “”){
cookiePath = “;Path=” + cookiePath;
}document.cookie = cookieName + “=” + cookieValue + “;Expires=” + cookieExpires + cookiePath;
Trang 14}document.imgAdvert.src = “AdvertImage” + imageNumber + “.jpg”;
</script>
</body>
</html>
Save this as ch11_q2.htm.This solution is based on similar questions in previous chapters, such as Chapter 9 where we displayed arandomly selected image In this case we display a different image in the page each time the user visits
it, as far as our selection of images allows
We’ve seen the cookie setting and reading functions earlier in the chapter, so let’s look at the new code
We store the number of the previously displayed images in a cookie named displayedImages The nextimage we display is that image number plus one Once all of our images have been displayed, we startagain at 1 If the user has never been to the web site, no cookie will exist so nullwill be returned fromgetCookieValue(), in which case we set imageNumberto 1
Most of the code is fairly self-explanatory, except perhaps these lines:
if (totalImages == imageNumber){
setCookie(“displayedImages”,””,””,”Mon, 1 Jan 1970 00:00:00”)}
What this bit of code does is delete the cookie by setting its expiration date to a date that has alreadypassed
Trang 15var boxTwo = document.getElementById(“boxTwo”);
boxOne.style.visibility = “visible”;
boxTwo.style.visibility = “hidden”;
}function showBoxTwo() {var boxOne = document.getElementById(“boxOne”);
var boxTwo = document.getElementById(“boxTwo”);
<a href=”#” onclick=”showBoxOne(); return false;”>Show First Box</a>
<a href=”#” onclick=”showBoxTwo(); return false;”>Show Second Box</a>
Trang 16In the body of the page, you find two <a/>elements and two <div/>elements The <a/>elements areset to handle the clickevent with the onclickattribute The first link calls the showBoxOne()JavaScript function, and the second link calls showBoxTwo() Both onclickevent handlers return avalue of false, which tells the browser not to navigate to the URL specified in the hrefattribute.
<a href=”#” onclick=”showBoxOne(); return false;”>Show First Box</a>
<a href=”#” onclick=”showBoxTwo(); return false;”>Show Second Box</a>
Next are the <div/>elements, which contain no content The only attribute specified is their idattributes
<div id=”boxOne”></div>
<div id=”boxTwo”></div>
In the <script/> element, two functions can be found: showBoxOne()and showBoxTwo() Their pose is to show one <div/>element while hiding the other The first, showBoxOne(), shows the firstbox
pur-function showBoxOne() {var boxOne = document.getElementById(“boxOne”);
var boxTwo = document.getElementById(“boxTwo”);
boxOne.style.visibility = “visible”;
boxTwo.style.visibility = “hidden”;
}The first step in this process is to retrieve the two <div/>elements by usingdocument.getElementById() Next, the visibilityproperty for boxOneis set to visible, whilethe same property for boxTwois set to hidden This shows the first box while hiding the other
The showBoxTwo()function follows the same idea, and for the most part, uses the same code asshowBoxOne()
function showBoxTwo() {var boxOne = document.getElementById(“boxOne”);
var boxTwo = document.getElementById(“boxTwo”);
boxOne.style.visibility = “hidden”;
boxTwo.style.visibility = “visible”;
}The only difference in this function is the values assigned to the two element’s visibilityproperties
In this case, boxOneis set to hiddenwhile boxTwois set to visible
Question 2
Create a <div/>element that floats around the page Use the edges of the browser’s viewport as aboundary
Trang 17var horizontalMovement = Math.ceil(Math.random() * 5);
var verticalMovement = Math.ceil(Math.random() * 5);
var currentLeft = floatingDiv.offsetLeft;
var currentTop = floatingDiv.offsetTop;
if (currentTop < 0) {verticalMovement = Math.ceil(Math.random() * 5);
} else if ( ( currentTop + floatingDiv.offsetHeight ) > screenHeight ) {verticalMovement = -(Math.ceil(Math.random() * 5));
}
if (currentLeft < 0) {horizontalMovement = Math.ceil(Math.random() * 5);
} else if ( ( currentLeft + floatingDiv.offsetWidth) > screenWidth ) {horizontalMovement = -(Math.ceil(Math.random() * 5));
}floatingDiv.style.left = currentLeft + horizontalMovement + “px”;floatingDiv.style.top = currentTop + verticalMovement + “px”;
}
</script>
</head>
<body onload=”startTimer()”>
Trang 18The style sheet in this page consists of only one rule, which is for the floatingDiv <div/>element.
#floatingDiv {position: absolute;
Now let’s look at the code At the top of the script block, five global, page-level variables are defined.These variables are accessible from any JavaScript function used in the web page
var floatingDiv;
var screenWidth;
var screenHeight;
var horizontalMovement = Math.ceil(Math.random() * 5);
var verticalMovement = Math.ceil(Math.random() * 5);
The floatingDivvariable will reference the <div/>element The screenHeightand screenWidthvariables will contain the height and width of the browser’s viewport, respectively These values areused to determine if the element has reached the edge of the viewport The final two global variables arehorizontalMovementand verticalMovement These contain random numbers and are between 1and
5 These hold the amount that the <div/>element should be moved each time the timer callsmoveDiv()
The first function, startTimer(), is called when the page loads Its job is to populate the floatingDiv,screenHeight, and screenWidthvariables with their values It also starts the animation
function startTimer() {floatingDiv = document.getElementById(“floatingDiv”);
screenWidth = document.body.clientWidth;
screenHeight = document.body.clientHeight;
window.setInterval(“moveDiv()”, 10);
}
Trang 19The floatingDivvariable gets its value by using the document.getElementById()method to retrievethe <div/>element in the page’s body By using the clientWidthand clientHeightproperties of thedocument.bodyobject, the screenWidthand screenHeightvariables get their values The final line ofthis function uses window.setInterval()to repeatedly call moveDiv()every 10 milliseconds.
The real workhorse of this example is the moveDiv()function, which moves the element around on thepage The first task is to find the element’s current top and left positions
function moveDiv() {
var currentLeft = floatingDiv.offsetLeft;
var currentTop = floatingDiv.offsetTop;
//more code here}
You do this by using the offsetLeftand offsetTopproperties of floatingDiv Next, the functionneeds to determine where the element should be moved This is done in two sections
The first section decides whether or not the element has reached the top or bottom of the page
function moveDiv() {
var currentLeft = floatingDiv.offsetLeft;
var currentTop = floatingDiv.offsetTop;
if (currentTop < 0) {verticalMovement = Math.ceil(Math.random() * 5);
} else if ( ( currentTop + floatingDiv.offsetHeight ) > screenHeight ) {verticalMovement = -(Math.ceil(Math.random() * 5));
}//more code here}
If the top of the element has reached the top of the page, then the <div/>needs to move downward.Therefore, the verticalMovementvariable is set to a random positive number between 1and 5thatmoves the element toward the bottom of the page If the bottom of the page has been reached by the ele-ment’s bottom, then the element needs to start moving back toward the top Therefore,
verticalMovementis assigned a negative random number between 1and 5
The second section determines whether or not the element has reached the right or left edge of thebrowser’s viewport
function moveDiv() {
var currentLeft = floatingDiv.offsetLeft;
var currentTop = floatingDiv.offsetTop;
if (currentTop < 0) {verticalMovement = Math.ceil(Math.random() * 5);
} else if ( ( currentTop + floatingDiv.offsetHeight ) > screenHeight ) {verticalMovement = -(Math.ceil(Math.random() * 5));
Trang 20if (currentLeft < 0) {horizontalMovement = Math.ceil(Math.random() * 5);
} else if ( ( currentLeft + floatingDiv.offsetWidth) > screenWidth ) {horizontalMovement = -(Math.ceil(Math.random() * 5));
}//more code here}
This new code follows the same principles as the top/bottom code First, it checks to see whether theelement has reached the left edge of the viewport If so, horizontalMovementis assigned a randompositive number to move the element to the right When the right edge of the element reaches the rightedge of the page, horizontalMovementis set to a random negative number, which moves the elementback to the left
The final step is to move the element to its new location
function moveDiv() {var currentLeft = floatingDiv.offsetLeft;
var currentTop = floatingDiv.offsetTop;
if (currentTop < 0) {verticalMovement = Math.ceil(Math.random() * 5);
} else if ( ( currentTop + floatingDiv.offsetHeight ) > screenHeight ) {verticalMovement = -(Math.ceil(Math.random() * 5));
}
if (currentLeft < 0) {horizontalMovement = Math.ceil(Math.random() * 5);
} else if ( ( currentLeft + floatingDiv.offsetWidth) > screenWidth ) {horizontalMovement = -(Math.ceil(Math.random() * 5));
}floatingDiv.style.left = currentLeft + horizontalMovement + “px”;
floatingDiv.style.top = currentTop + verticalMovement + “px”;
}This code uses the styleobject and leftand topproperties to set the new left and top positions for the
<div/>element The new leftposition is set to the element’s current left plus the number contained inhorizontalMovement, and the new topposition is set to the element’s current top plus
verticalMovement At the end of both statements, the string pxis appended to the value, making surethat the browser will position the element correctly
Chapter 13
In this chapter you looked at the DOM and how the standard method for accessing objects on the HTMLdocument can be applied in JavaScript and used to create web pages that will work in both majorbrowsers
Trang 21Question 1
Here’s some HTML code that creates a web page Re-create this page, using JavaScript to generate theHTML using only DOM objects, properties, and methods Test your code in IE, Firefox, Opera, andSafari (if you have it) to make sure it works in them
Hint: Comment each line as you write it to keep track of where you are in the tree structure, and create a new variable for every element on the page (for example, not just one for each of the TD cells, but nine variables).
Trang 22var THElem = document.createElement(“thead”)var TRElem1 = document.createElement(“TR”)var TRElem2 = document.createElement(“TR”)var TRElem3 = document.createElement(“TR”)var TDElem1 = document.createElement(“TD”)var TDElem2 = document.createElement(“TD”)var TDElem3 = document.createElement(“TD”)var TDElem4 = document.createElement(“TD”)var TDElem5 = document.createElement(“TD”)var TDElem6 = document.createElement(“TD”)var TDElem7 = document.createElement(“TD”)var TDElem8 = document.createElement(“TD”)var TDElem9 = document.createElement(“TD”)var TBODYElem = document.createElement(“TBODY”)var TextNodeA1 = document.createTextNode(“Car”)var TextNodeA2 = document.createTextNode(“Top Speed”)var TextNodeA3 = document.createTextNode(“Price”)var TextNodeB1 = document.createTextNode(“Chevrolet”)var TextNodeB2 = document.createTextNode(“120mph”)var TextNodeB3 = document.createTextNode(“$10,000”)var TextNodeC1 = document.createTextNode(“Pontiac”)var TextNodeC2 = document.createTextNode(“140mph”)var TextNodeC3 = document.createTextNode(“$14,000”)docNavigate = document.documentElement; //Starts with HTML documentdocNavigate = docNavigate.lastChild; //Moves to body elementdocNavigate.appendChild(TableElem); //Adds the table elementdocNavigate = docNavigate.lastChild; //Moves to the table elementdocNavigate.appendChild(THElem); //Adds the thead elementdocNavigate = docNavigate.firstChild; //Moves to the thead elementdocNavigate.appendChild(TRElem1); //Adds the TR elementdocNavigate = docNavigate.firstChild; //Moves the TR elementdocNavigate.appendChild(TDElem1); //Adds the first TD element in the
// headingdocNavigate.appendChild(TDElem2); //Adds the second TD element in the
// headingdocNavigate.appendChild(TDElem3); //Adds the third TD element in the
// headingdocNavigate = docNavigate.firstChild; //Moves to the first TD elementdocNavigate.appendChild(TextNodeA1); //Adds the second text nodedocNavigate = docNavigate.nextSibling; //Moves to the next TD elementdocNavigate.appendChild(TextNodeA2); //Adds the second text nodedocNavigate = docNavigate.nextSibling; //Moves to the next TD elementdocNavigate.appendChild(TextNodeA3); //Adds the third text nodedocNavigate = docNavigate.parentNode; //Moves back to the TR elementdocNavigate = docNavigate.parentNode; //Moves back to the thead elementdocNavigate = docNavigate.parentNode; //Moves back to the table elementdocNavigate.appendChild(TBODYElem); //Adds the tbody element
docNavigate = docNavigate.lastChild; //Moves to the tbody elementdocNavigate.appendChild(TRElem2); //Adds the second TR elementdocNavigate = docNavigate.lastChild; //Moves to the second TR elementdocNavigate.appendChild(TDElem4); //Adds the TD element
docNavigate.appendChild(TDElem5); //Adds the TD elementdocNavigate.appendChild(TDElem6); //Adds the TD element
Trang 23docNavigate = docNavigate.firstChild; //Moves to the first TD element
docNavigate.appendChild(TextNodeB1); //Adds the first text node
docNavigate = docNavigate.nextSibling; //Moves to the next TD element
docNavigate.appendChild(TextNodeB2); //Adds the second text node
docNavigate = docNavigate.nextSibling; //Moves to the next TD element
docNavigate.appendChild(TextNodeB3); //Adds the third text node
docNavigate = docNavigate.parentNode; //Moves back to the TR element
docNavigate = docNavigate.parentNode; //Moves back to the tbody element
docNavigate.appendChild(TRElem3); //Adds the TR element
docNavigate = docNavigate.lastChild; //Moves to the TR element
docNavigate.appendChild(TDElem7); //Adds the TD element
docNavigate.appendChild(TDElem8); //Adds the TD element
docNavigate.appendChild(TDElem9); //Adds the TD element
docNavigate = docNavigate.firstChild; //Moves to the TD element
docNavigate.appendChild(TextNodeC1); //Adds the first text node
docNavigate = docNavigate.nextSibling; //Moves to the next TD element
docNavigate.appendChild(TextNodeC2); //Adds the second text node
docNavigate = docNavigate.nextSibling; //Moves to the next TD element
docNavigate.appendChild(TextNodeC3); //Adds the third text node
Hint: Add any extra code to the end of the script code you have already written.
Trang 25<script type=”text/javascript” language=”javascript”>
function createDocument(){
//Temporary DOM object
var xmlDoc;
//Create the DOM object for IE
if (window.ActiveXObject){
var versions = [
return xmlDoc;
} catch (error) {
//do nothing here}
}}//Create the DOM for Firefox and Operaelse if (document.implementation && document.implementation.createDocument) {
xmlDoc = document.implementation.createDocument(“”,””,null);
return xmlDoc;
}return null;
}var xmlDoc = createDocument();
xmlDoc.load(“school.xml”);
function writeTableOfSchoolChildren(){
var xmlNode = xmlDoc.getElementsByTagName(‘child’);
var newTableElement = document.createElement(‘table’);
Trang 26var tableRow = document.createElement(‘TR’);
for (var iRow= 0; iRow < xmlNode[i].childNodes.length; iRow++){
if (xmlNode[i].childNodes[iRow].nodeType != 1){
continue;
}var tdElement = document.createElement(‘TD’);
var textData = document.createTextNode(xmlNode[i].childNodes[iRow].firstChild.nodeValue);
tdElement.appendChild(textData);
tableRow.appendChild(tdElement);
}tempElement.appendChild(tableRow);
}document.getElementById(‘displaySchoolInfo’).appendChild(newTableElement);}
</script>
</head>
<body>
<p>
<a href=”javascript: writeTableOfSchoolChildren()”>
Show Table of Children At The School
Trang 27document.real1.DoPlay();
}
function window_onload() {var plugInInstalled = false;
if (navigator.appName.indexOf(“Microsoft”) == -1){
plugInInstalled = truebreak;
}}}else{
if (real1.readyState == 4)plugInInstalled = true;
}
if (plugInInstalled == false)window.location.replace(“NoRealAudioPage.htm”);
}
</script>
<object classid=”clsid:CFCDAA03-8BE4-11CF-B84B-0020AFBBCCFA” id=”real1”viewastext>
<param name=”height” value=”0”>
<param name=”width” value=”0”>
<embed name=”real1” id=”real1” border=”0” controls=”play” height=”0”width=”0” type=”audio/x-pn-realaudio-plugin”>
Trang 28<a onmouseover=”play(‘Explosion.ra’)” onmouseout=”document.real1.DoStop();”href=”#”>
Just as the IE and Firefox support for plug-ins is different, so therefore are the means of checking forplug-ins For Firefox, go through the navigatorobject’s pluginsarray and check each installed plug-infor the name RealPlayer; if it’s found, you know the user has the RealAudio player installed
With IE, simply use the real1ActiveX control’s readyStateproperty to see if it’s installed and ized correctly
initial-To play the sounds, a function called play()is defined whose parameter is the name of the ra(or rm)sound file to be played
function play(fileName){
document.real1.SetSource(fileName);
document.real1.DoPlay();
}The function makes use of the RealAudio player’s setSource()method to set the sound file to beplayed and the DoPlay()method to actually start playing the clip You have used different sounds foreach link by simply specifying a different file name each time as the parameter for the play()function.Use the onmouseoverand onmouseoutevent handlers to start playing the sound when the mousepointer is over the link and to stop it when the mouse pointer moves out of the link, respectively Themouseoutevent starts playing the audio clip by calling the play()function, and the mouseouteventstops playing it by calling the RealPlayer’s DoStop()method
<a onmouseover=”play(‘audiosig.ra’)” onmouseout=”document.real1.DoStop()” href=”#”>Evil Laugh
</a>
Chapter 16
This chapter introduced you to the concept of remote scripting You wrote a JavaScript class to easilyperform asynchronous HTTP requests and created two forms that used Ajax to validate their fields
Trang 29var oHttp = new XMLHttpRequest();
return oHttp;
}else if (window.ActiveXObject){
var versions = [
return oHttp;
}catch (error){
//do nothing here}
}}return null;
Trang 30{var tempRequest = this.request;
var fpCallback = this.callBack;
function request_readystatechange(){
if (tempRequest.readyState == 4){
if (tempRequest.status == 200){
fpCallback(tempRequest.responseText);
}else{alert(“An error occurred while attempting to contact theserver.”);
}}}this.request.onreadystatechange = request_readystatechange;
}this.request.send(null);
if (!this.async){
this.callBack(this.request.responseText);
}}It’s possible to add synchronous communication to your HttpRequestclass in a variety of ways Theapproach in this solution refactors the code to accommodate a new property called async, which con-tains either trueor false If it contains true, then the class uses asynchronous communication toretrieve the file, and if it contains false, the class uses synchronous communication In short, this prop-erty resembles an XML DOM’s asyncproperty for determining how an XML document is loaded.The first change made to the class is in the constructor itself The original constructor initializes andreadies the XMLHttpRequest(XHR) object to send data This will not do for this new version, however.Instead, the constructor merely initializes all the properties
function HttpRequest(sUrl, fpCallback){
Trang 31The new constructor and class properties are actually desirable, as they enable you to reuse the sameHttpRequestobject for multiple requests If you wanted to make a request to a different URL, all youwould need to do is assign the urlproperty a new value The same can be said for the callback function
var oHttp = new XMLHttpRequest();
return oHttp;
}else if (window.ActiveXObject){
var versions =[
return oHttp;
}catch (error){
//do nothing here}
}}return null;
}
The majority of changes to the class are in the send()method It is here that the class decides whether touse asynchronous or synchronous communication Both types of communication have very little in com-mon when it comes to making a request; asynchronous communication uses the onreadystatechangeevent handler, and synchronous communication allows access to the XHR object’s properties when therequest is complete Therefore, code branching is required
HttpRequest.prototype.send = function()
{
this.request.open(“GET”, this.url, this.async);
if (this.async){
Trang 32//more code here}
this.request.send(null);
if (!this.async){
//more code here}
}The first line of this method uses the open()method of the XHR object The asyncproperty is used asthe final parameter of the method This determines whether or not the XHR object uses asynchronouscommunication Next comes an ifstatement, which tests to see if this.asyncis true; if it is, the asyn-chronous code will be placed in this ifblock Next, the XHR object’s send()method is called, sendingthe request to the server The final ifstatement checks to see whether this.asyncis false If it is, syn-chronous code is placed here to execute
HttpRequest.prototype.send = function(){
this.request.open(“GET”, this.url, this.async);
if (this.async){
var tempRequest = this.request;
var fpCallback = this.callBack;
function request_readystatechange(){
if (tempRequest.readyState == 4){
if (tempRequest.status == 200){
fpCallback(tempRequest.responseText);
}else{alert(“An error occurred while attempting to contact theserver.”);
}}}this.request.onreadystatechange = request_readystatechange;
}this.request.send(null);
if (!this.async){
this.callBack(this.request.responseText);
}}
Trang 33This new code finishes off the method Let’s start with the first ifblock A new variable called
fpCallbackis assigned the value of this.callBack This is done for the same reasons as with thetempRequestvariable — scoping issues — as thispoints to the request_readystatechange()func-tion instead of the HttpRequestobject Other than this change, the asynchronous code remains thesame The request_readystatechange()function handles the readystatechangeevent and callsthe callback function when the request is successful
The second ifblock is much simpler Because this code executes only if synchronous communication isdesired, all you have to do is call the callback function and pass the XHR’s responseTextproperty.Using this newly refactored class is quite simple The following code makes an asynchronous request for
a fictitious text file called test.txt
Trang 34text-align: right;
}.submit{text-align: right;
if (sResponseText == “available”){
isUsernameTaken = false;
}else {isUsernameTaken = true;
}}function checkEmail_callBack(sResponseText) {
if (sResponseText == “available”) {
isEmailTaken = false;
} else {isEmailTaken = true;
}}function form_submit() {
var request = new HttpRequest();
request.async = false;
//First check the usernamevar userValue = document.getElementById(“username”).value;
if (userValue == “”) {
alert(“Please enter a user name to check!”);
return false;
}request.url = “formvalidator.php?username=” + userValue;
Trang 35request.callBack = checkUsername_callBack;
request.send();
if (isUsernameTaken) {
alert(“The username “ + userValue + “ is not available!”);return false;
}//Now check the emailvar emailValue = document.getElementById(“email”).value;
if (emailValue == “”) {
alert(“Please enter an email address to check!”);
return false;
}request.url = “formvalidator.php?email=” + emailValue;
request.callBack = checkEmail_callBack;
request.send();
if (isEmailTaken) {
alert(“I’m sorry, but “ + emailValue + “ is in use by “ +
“another user.”);
return false;
}//If the code’s made it this far, everything’s goodreturn true;
Trang 36The JavaScript code holds the most changes, so let’s get started there In this new implementation, twoglobal variables, called isUsernameTakenand isEmailTaken, are declared These variables hold true
or falsevalues: trueif the user name or e-mail is taken, and falseif it is not
var isUsernameTaken;
var isEmailTaken;
function checkUsername_callBack(sResponseText) {
if (sResponseText == “available”) {
isUsernameTaken = false;
} else {isUsernameTaken = true;
}}function checkEmail_callBack(sResponseText)
Trang 37if (sResponseText == “available”) {
isEmailTaken = false;
} else {isEmailTaken = true;
}}
The first two functions, checkUsername_callBack()and checkEmail_callBack(), are somewhatsimilar to their original versions Instead of alerting information to the user, however, they simply assignthe isUsernameTakenand isEmailTakenvariables their values
The function that performs most of the work is form_submit() It is responsible for making therequests to the server and determines if the data in the form fields are ready for submission
alert(“Please enter a user name to check!”);
return false;
}request.url = “formvalidator.php?username=” + userValue;
Trang 38request.callBack = checkUsername_callBack;
request.send();
if (isUsernameTaken) {
alert(“The username “ + userValue + “ is not available!”);
return false;
}//more code here}
This code retrieves the value of the Usernamefield and checks to see whether any information wasentered If none was entered, a message is alerted to the user informing her to enter data If the userentered information in the Usernamefield, then code execution continues The urland callBackprop-erties are assigned their values and the request is sent to the server If it turns out that the user’s desireduser name is taken, an alert box tells her so Otherwise, the code continues to execute and checks thee-mail information:
function form_submit() {
var request = new HttpRequest();
request.async = false;
//First check the usernamevar userValue = document.getElementById(“username”).value;
if (userValue == “”) {
alert(“Please enter a user name to check!”);
return false;
}request.url = “formvalidator.php?username=” + userValue;
request.callBack = checkUsername_callBack;
request.send();
if (isUsernameTaken) {
alert(“The username “ + userValue + “ is not available!”);
return false;
}//Now check the emailvar emailValue = document.getElementById(“email”).value;
if (emailValue == “”) {
alert(“Please enter an email address to check!”);
return false;
}request.url = “formvalidator.php?email=” + emailValue;
request.callBack = checkEmail_callBack;
Trang 39if (isEmailTaken) {
alert(“I’m sorry, but “ + emailValue + “ is in use by another user.”);return false;
}//If the code’s made it this far, everything’s goodreturn true;
}
The e-mail-checking code goes through the same process that was used to check the user name Thevalue of the Emailfield is retrieved and checked to determine whether the user typed anything into thetext box Then that value is used to make another request to the server Notice again that the urlandcallBackproperties are explicitly set If isEmailTakenis true, an alert box shows the user that anotheruser has taken the e-mail address and the function returns false If the address is available, the functionreturns true, thus making the browser submit the form
Trang 40Index
SYMBOLS AND NUMERICS
& (ampersand), XML (Extensible Markup guage) character data, 555–556
Lan-&& (AND), logical operator, 70–72
’ (apostrophe), XML (Extensible Markup guage) character data, 555–556
Lan-* (asterisk), repetition character, 304–305
&, entity reference, 555–556
', entity reference, 555–556
>, entity reference, 555–556
<, entity reference, 555–556
 , space symbol, 23
<A>tag, event handlers and the, 170–175
\ (backslash), escape character, 23
\’ (backslash apostrophe), escape sequence,23
\” (backslash quote), escape sequence, 23
\\ (double backslash), escape sequence, 23
\bescape sequence, 23position character, 305–308
\\b, regular expression, 324–329
^ (caret), position character, 305–308[^ ] (caret and periods in brackets), characterclass, 300–304
© (copyright symbol), inserting in a string, 23{} (curly braces), marking out a block of codewith, 67
— (decrement), operators, 37–39
\d, character class, 300–304, 300–304
$ (dollar sign), position character, 305–308
== (double equal to sign), operator symbol, 65
!= (exclamation point equal to), operator bol, 65
sym-\f, escape sequence, 23
> (greater than)operator symbol, 65XML (Extensible Markup Language) characterdata, 555–556
>= (greater than or equal to), operator symbol,65
++ (increment), operators, 37–39
<img>tag, exercise questions, 186, 671
< (less than)operator symbol, 65XML (Extensible Markup Language) characterdata, 555–556
<= (less than or equal to), operator symbol, 65
! (NOT), logical operator, 70–72
\n, escape sequence, 23
|| (OR), logical operator, 70–72 (period), character class, 300–304[ ] (periods in brackets), character class,300–304
+ (plus sign), repetition character, 304–305
# (pound sign), CSS (Cascading Style Sheets)and the, 471