• Share
  • Email
  • Embed
  • Like
  • Save
  • Private Content
06 - JavaScript and AJAX
 

06 - JavaScript and AJAX

on

  • 617 views

 

Statistics

Views

Total Views
617
Views on SlideShare
617
Embed Views
0

Actions

Likes
0
Downloads
0
Comments
0

0 Embeds 0

No embeds

Accessibility

Categories

Upload Details

Uploaded via as Microsoft Word

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

    06 - JavaScript and AJAX 06 - JavaScript and AJAX Document Transcript

    • DOM Review Last time we manipulated the DOM to replace text with the output of a JavaScript simulation. The same idea can be used to switch images, for example to pull a rabbit out of a hat. Let’s start with a simple image of a top hat (of course you need to download the image from our web site first): <html> <head> <title>Magic</title> <style> </head> <body> <h1 class="center">A Magic Trick</h1> <p> <img src="topHat.gif"/> </p> <p>Title</p> </body> </html> We add ids, scripts, etc, similar to before, but instead of replacing the “innerHTML” of some text we replace the “src” attribute of the image tag. We also use a boolean variable rabbitVisible so we can tell which image is currently shown. The variable is placed outside any function so it executes only once when the page loads. <head> <meta content="text/html; charset=utf-8" http-equiv="Content-Type" /> <title>Magic</title> <script language="javascript" type="text/javascript"> var rabbitVisible = false; function magic() { var image = document.getElementById("hat"); if (rabbitVisible) { image.setAttribute("src", "topHat.gif"); rabbitVisible = false; } else { image.setAttribute("src", "rabbit-hat.gif"); rabbitVisible = true; } } </script> </head> <body> <h1 class="center">A Magic Trick</h1> <p> <img src="topHat.gif" id="hat" onclick="magic()"/> </p> <p>Title</p> </body>
    • </html> To make it look perfect, we add a table to force the top hat to stay at the same height as the rabbit-expanded hat. The script remains the same. <body> <h1 class="center">A Magic Trick</h1> <table align="center"> <tr><td height="500" valign="bottom"> <img src="topHat.gif" id="hat" onclick="magic()"/> </td></tr> </table> </body> Return to our extended Example We want to find an approximation of the number (Pi) experimentally. To do this we imagine a cannon that shoots a ball into a square with corners (1,1), (-1,1), (-1,-1), (1,-1). We assume that the ball always lands inside that square, but at completely random locations. In particular, sometimes the balls falls inside a circle of radius 1 centered at the origin, other times it falls outside that circle: If T is the total number of shots, and I is the number of times the ball lands inside the circle, we finally compute We already wrote the basic program with the output appearing in an alert dialog. Now we’ll take a different approach, where we want to display instructions, offer the user a ‘Go’ button, and then see the results displayed in the existing page. No problem. Attempt 3:
    • <html> <head> <title>Experimenting with Randomness 3</title> <script language="javascript" type="text/javascript"> function simulateCannon() { var totals = 1000.0; var inside = 0.0; var fieldTotals = document.getElementById("totals"); var fieldInside = document.getElementById("inside"); var fieldAnswer = document.getElementById("answer"); for (var count = 1; count <= totals; count++) { var x = 2.0 * Math.random() - 1.0; var y = 2.0 * Math.random() - 1.0; var r = Math.sqrt(x*x + y*y); if (r < 1) { inside++; } } fieldTotals.innerHTML = "" + totals; fieldInside.innerHTML = "" + inside; fieldAnswer.innerHTML = "" + 4.0 * inside / totals; } </script> </head> <body> <h1>Experimenting with Randomness 3</h1> <p align="center"> <img alt="Cannon shooting inside Square" src="cannon_square.jpg"> </p> <ul> <li>Total shots: <span id="totals">0.0</span></li> <li>Inside circle: <span id="inside">0.0</span></li> <li>Estimation: <span id="answer">0.0</span></li> </ul> <form> <input type="button" value="Shoot" onclick="simulateCannon()"> de Cannon </form> </body> </html> Finally we use a text field so that a user can type in the desired amount of tries themselves. This time, instead of setting or changing a value on the DOM we read what the user enters and use that value in our program. Attempt 4: <html> <head> <title>Experimenting with Randomness 4</title> <script language="javascript" type="text/javascript"> function simulateCannon() { var inputTotals = document.getElementById("input");
    • var totals = inputTotals.value; var inside = 0.0; var fieldTotals = document.getElementById("totals"); var fieldInside = document.getElementById("inside"); var fieldAnswer = document.getElementById("answer"); for (var count = 1; count <= totals; count++) { var x = 2.0 * Math.random() - 1.0; var y = 2.0 * Math.random() - 1.0; var r = Math.sqrt(x*x + y*y); if (r < 1) { inside++; } } fieldTotals.innerHTML = "" + totals; fieldInside.innerHTML = "" + inside; fieldAnswer.innerHTML = "" + 4.0 * inside / totals; } </script> </head> <body> <h1>Experimenting with Randomness 4</h1> <p align="center"> <img alt="Cannon shooting inside Square" src="cannon_square.jpg"> </p> <ul> <li>Total shots: <span id="totals">0.0</span></li> <li>Inside circle: <span id="inside">0.0</span></li> <li>Estimation: <span id="answer">0.0</span></li> </ul> <form> <input type="button" value="Shoot" onclick="simulateCannon()"> de Cannon <input type="text" value="1000" size="10" id="input"> times. </form> </body> </html> Next, let’s go back to one of the other primary functions of JavaScript: to improve the look of a document. Switching Style Sheets We learned how to attach multiple style sheets to a document, which all ‘cascade’ into one style. You can also define alternate style sheets so that the user can switch between them to give a page the look they prefer. You can, for example: • use a default style sheet for your average user • provide an alternate style sheet with large print for users with poor eye sight • provide another style sheet in gray-scale to use for printing • use yet another style sheet to optimize your content to viewers with small devices (smart phones)
    • Of course we need (at least) two style sheets. For simplicity, let’s create two very simple style sheets right now: File style1.css /* Simple style sheet using entire width of screen */ body { margin: 10px; width: 100%; } h1 { background-color: blue; color: yellow; } .justified { text-align: left; } File style2.css /* Style suitable for small device such as smart phone */ body { margin: 10px auto; width: 480px; } h1 { background-color: yellow; color: blue; } .justified { text-align: right; } Now let’s create a simple HTML file with the first style sheet attached: File style-test.html <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta content="text/html; charset=utf-8" http-equiv="Content-Type" /> <title>Style Switcher</title> <link href="style1.css" rel="stylesheet" type="text/css" /> </head> <body> <h1>Style Switcher</h1> <p class="justified">This is some text.</p> </body>
    • </html> As usual, the style determines the look of the header and paragraph, as we learned some time ago. To add the second style sheet as an alternate style, we give our first style sheet a title and then add the alternate sheet as follows (bold lines have changed): <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta content="text/html; charset=utf-8" http-equiv="Content-Type" /> <title>Style Switcher</title> <link href="style1.css" rel="stylesheet" type="text/css" title="Default Style" /> <link href="style2.css" rel="alternate stylesheet" type="text/css" title="Mobile Style" /> </head> <body> <h1>Style Switcher</h1> <p class="justified">This is some text.</p> </body> </html> Save the modified HTML document and view your main page in Firefox (not IE, and not in design) – nothing has changed! But now select from the Firefox menu “View | Page Style” and pick you alternate style! Pretty cool (I hope you think) but there are two disadvantages: • the new style does not ‘stick’ and has to be re-selected every time • this is not supported by Internet Explorer!! We need to develop a method to switch styles that remedies both problems. That’s where JavaScript comes in! First we need to give the two style tags an ID so that we can reference them in the DOM. Add the following to the style tags above: <link href="style1.css" rel="stylesheet" type="text/css" title="Default Style" id="default" /> <link href="style2.css" rel="alternate stylesheet" type="text/css" title="Mobile Style" id="mobile" /> Now we can add the script to get the style elements and swap them. We’ll create a new function for that and add it to the header: <script type="text/javascript"> function switch_style() { style_default = document.getElementById("default"); style_mobile = document.getElementById("mobile"); if (style_default.disabled)
    • { style_default.disabled = false; style_mobile.disabled = true; } else { style_default.disabled = true; style_mobile.disabled = false; } } </script> Now all we need is a trigger to call the function. We could use, for example, a button: <form> <input type="button" value="Switch style" onclick="switch_style()" /> </form> Now you should be able to put everything together for a style-switching page that will work in every modern web browser. BUT, the style switch does not stick, i.e. does not persist between pages or visits. In other words, if we visit the page again at a later time, the default style will be valid again, and if we switch to another pages, our choice of styles will not be saved. The solution here is cookies. Cookies Cookies are small chunks of data that are saved by your browser. A web page can cause your browser to save data in a cookie and the same or another page can later retrieve the saved data. The JavaScript cookie is a document object with the following parameters: • name: the name of the cookie • expires: the date/time when the cookie expires automatically • path: the path of a cookie • domain: the name of the server that created the cookie • secure: whether to use encryption to read/set cookie Since cookies represent data stored automatically by a web page on your computer they might pose certain security and privacy risks. The data could contain a virus, for example, or cookies can be (and are) are used to identify and follow individual access to web pages. For example, when you visit page X, you could receive a cookie with a unique identifier. When you later return to the page, it can check the value of the cookie and know whether you visited the page before, and when. Note that it can identify you as a unique user but it does not know your actual identity (name, address, etc). To help protect your computer, cookies follow some rules: • Only small amounts of data can be stored in a cookie • Cookies are available via JavaScript only to the domain used when the cookie was created
    • • Cookies are available only to files in the same directory the cookie was created in (to make a cookie available to all files use as path “/”) • Cookies can be manually manipulated in a web browser. In Firefox: o Tools -> Options -> Privacy -> Show Cookies will show all cookies stored o Tools -> Options -> Privacy lets you decide whether browser accepts cookies o Tools -> Clear Private Data lets you delete all stored cookies How to set a cookie: To set a cookie, you assign an appropriate value to “document.cookie”. It will automatically add your cookie to other cookies from your domain that might exist already to form a string of cookies. The cookie must follow a certain format. At a minimum it is: name=value;expires=date;path=mypath Here is some sample code. First we provide a framework with some functions and buttons to test them: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta content="text/html; charset=utf-8" http-equiv="Content-Type" /> <title>Cookie Tester</title> <script language="javascript" type="text/javascript"> function setCookie(name, value, expireDays) { alert("Set cookie"); } function showCookies() { alert("My cookies: " + document.cookie); } function getCookie() { alert("Get Cookie"); } function delCookie() { alert("Delete Cookie"); } </script> </head> <body> <h1>Cookie Tester</h1> <input type="button" value="Show cookies" onclick="showCookies()"/> <input type="button" value="Set cookie" onclick="setCookie()"/> <input type="button" value="Get cookie" onclick="getCookie()"/> <input type="button" value="Delete cookie" onclick="delCookie()"/>
    • </body> </html> Save and test the document (the alert boxes are just for demonstration and will be removed later). Note that the showCookies will not show any cookies. That does not mean there are no cookies, only that there are no cookies from our current domain (yet). Now let’s fill in the setCookie function: a typical cookie has a value of the form: name=”text”;expires=”Sun, 14 Jun 2009 16:16:42 GMT”;path=”/” We change our function setCookie to accept some input parameters and define it as follows: function setCookie(name, value, expireDays) { var expires = new Date(); expires.setDate(expires.getDate() + expireDays); var myCookie= name + "=" + escape(value) + ";expires=" + expires.toGMTString() + ";path=/"; document.cookie = myCookie; alert("Set cookie:" + myCookie); } A few things to note: • Our function requires three inputs: the name of the cookie, the value of the cookie, and the number of days from today when the cookie should expire. Other parameters are possible as well • We create a new date, add the number of days to it, and use the result to define an appropriate expiration date object, which we convert to GMT to ensure it’s in the format cookies like. • To set the name=value we use the escape function for the value. That function is a JavaScript function to turn an arbitrary string into a safe and proper http string: no ‘funny’ escape characters for potential hanky- panky, replace special characters by proper HTML escape characters (e.g. a space by %20, a semicolon ; by %3B, a < by %3C, > by %3E, etc). That avoids the possibility of planting a virus in a cookie in case the value is typed by a user, and to use characters with special meanings such as < and > • We always use the path=/ to allow access to the cookie from all directories by default Incidentally, we need to change the way we call the function, since it now requires parameters. Try this: <input type="button" value="Set cookie" onclick="setCookie('user','Bert Wachsmuth', 1)"/> Set the cookie, then show all cookies. Note that document.cookie will only show the name=value combination of our cookies, not the details like expiration date, path, etc. How to delete a cookie: To delete a cookie is easy: we simply set the name of the cookie to an empty string and expire it yesterday. Even better, we can use the setCookie method to do the work for us: function delCookie(name)
    • { alert("Delete Cookie: " + name); setCookie(name, "", -1); } And since our function now requires as input the name of the cookie to delete, we’ll need to modify our button event handler: <input type="button" value="Delete cookie" onclick="delCookie('user')" /> How to retrieve the value of a cookie: This is a little trickier: if document.cookie is not empty it consists of “name=value” pairs, separated by semi-colons. So if the list is not empty we split it at the semicolons into an array, each entry now being a name=value pair. Then we go through the array, split each entry at the equal sign and check the name until we find the right one. NOTE: Here we reap the benefit of having used the escape function to set a cookie – why (hint: think semicolon) Fortunately, splitting is easy thanks to the build-in split function that can be invoked on strings. It splits a string at the specified character and returns an array corresponding to the parts of the original string. For example if s=”one;two;three” then s.split returns the array [“one”, “two”, “three”]. A little complication arises because cookies are actually separated by a semi-colon and a space. To remove extra leading spaces, we define a new function removeLeadingSpace. Also, when we finally find the value of the cookie, we ‘unescape’ it before returning it, to undo the changes of the ‘escape’ function we used to set the cookie’s value. Here is the code: function removeLeadingSpace(s) { while ((s != null) && (s.length > 0) && (s.charAt(0) == ' ')) s = s.substring(1,s.length); return s; } function getCookie(name) { if ((document.cookie == null) || (document.cookie == "")) { return ""; } else { var cookies = document.cookie.split(';'); for (var i = 0; i < cookies.length; i++) { var cookie = cookies[i].split('='); if (removeLeadingSpace(cookie[0]) == name) { return unescape(cookie[1]); } } return ""; } }
    • Of course we need to change the corresponding event handler to search for a cookie by name: <input type="button" value="Get cookie" onclick="alert(getCookie('user'))" /> We have, actually, created three (or four) universally useful functions to work with cookies. We can put these functions in a separate file, clean up the alert calls, add comments for better readability, and we can then use them in any of our pages dealing with cookies. Actually, I added a check to only set a cookie when the name is not empty – take a look. Loading JavaScript from an external file In other words, create a new file of type JavaScript, put the following code into it (the above functions minus the alert calls plus comments), and save as “cookiecutters.js” in a directory of your choice on your web site: File cookiecutters.js /* JavaScript library to handle Cookies. Provides the following functions: * * removeLeadingSpace(s) removes leading spaces from string s * setCookie(name, vale, expireDays) sets named cookie with given value * getCookie(name) returns value of named cookie * delCookie(name) deletes named cookie * showCookies() show all cookies in an alert box * * Author: Bert Wachsmuth * Version: June 13, 2009 */ /* Returns the string s without leading spaces. */ function removeLeadingSpace(s) { while ((s != null) && (s.length > 0) && (s.charAt(0) == ' ')) s = s.substring(1,s.length); return s; } /* Creates a cookie with the given name, value, and days after today to expire */ function setCookie(name, value, expireDays) { if (!((name == null) || (name == ""))) { var expires = new Date(); expires.setDate(expires.getDate() + expireDays); var myCookie= name + "=" + escape(value) + ";expires=" + expires.toGMTString() + ";path=/"; document.cookie = myCookie; } } /* Shows all cookies from the current host in an alert box */ function showCookies() { alert("My cookies: " + document.cookie); } /* Returns value of the named cookie or an empty string if cookie not found */ function getCookie(name) { if ((document.cookie == null) || (document.cookie == ""))
    • { return ""; } else { var cookies = document.cookie.split(';'); for (var i = 0; i < cookies.length; i++) { var cookie = cookies[i].split('='); if (removeLeadingSpace(cookie[0]) == name) { return unescape(cookie[1]); } } return ""; } } /* Deletes the cookie with the given name if possible */ function delCookie(name) { setCookie(name, "", -1); } Before we use our new functions we should test them extensively. The next HTML file will do just that: it loads the script from file and then lets you create/retrieve/delete cookies at will (note the use of named forms and form elements): <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta content="text/html; charset=utf-8" http-equiv="Content-Type" /> <title>Cookie Tester</title> <script language="javascript" type="text/javascript" src="cookiecutter.js"> </script> </head> <body> <h1>Cookie Tester</h1> <form name="form"> <p>Cookie name: <input type="text" name="name" /></p> <p>Cookie value: <input type="text" name="content" /></p> <p> <input type="button" value="Show cookies" onclick="showCookies()" /> <input type="button" value="Set cookie" onclick="setCookie(document.form.name.value,document.form.content.value,1)" /> <input type="button" value="Get cookie" onclick="alert(getCookie(document.form.name.value))" /> <input type="button" value="Delete cookie" onclick="delCookie(document.form.name.value)" /> </p> </form> </body> </html>
    • Now we are FINALLY ready to switch styles permanently. The idea is to use our cookie-handling routines to plant a cookie about the style the user selected so that the next time the page is visited, the selected style can be restored. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta content="text/html; charset=utf-8" http-equiv="Content-Type" /> <title>Style Switcher 2</title> <link href="style1.css" rel="stylesheet" type="text/css" title="Default Style" id="default" /> <link href="style2.css" rel="alternate stylesheet" type="text/css" title="Mobile Style" id="mobile" /> <script language="javascript" type="text/javascript" src="cookiecutter.js"> </script> <script language="javascript" type="text/javascript"> function setStyle() { var style = getCookie("bgw-style"); if ((style == null) || (style == "") || (style == "default")) { switch_to_default(); } else { switch_to_mobile(); } } function switch_to_default() { style_default = document.getElementById("default"); style_mobile = document.getElementById("mobile"); style_default.disabled = false; style_mobile.disabled = true; setCookie("bgw-style", "default", 365); } function switch_to_mobile() { style_default = document.getElementById("default"); style_mobile = document.getElementById("mobile"); style_default.disabled = true; style_mobile.disabled = false; setCookie("bgw-style", "mobile", 365); } </script> </head> <body onload="setStyle()"> <h1>Style Switcher 2</h1> <p align="center"> Use style:
    • [ <a href="javascript:switch_to_default()">default</a> ] [ <a href="javascript:switch_to_mobile()">mobile</a> ] </p> <p class="justified">This is some text.</p> </body> </html> Note that the function setStyle is called when the page is loading so that it can use the value of the cookie to determine the last style a user selected, if any. Timers and Recursion JavaScript provides easy access to a timer via the window functions setTimeout(‘function()’, millisecs) and clearTimeout(var), where the input to the clearTimer method is the return value of the setTimer function. Here are a few examples. Simple timer: <head> <script language="javascript" type="text/javascript"> function delayedAlert() { var timer = window.setTimeout("alert('Time is up')", 5000); } </script> </head> <body <input type="button" value="Start timer" onclick="delayedAlert()" /> </form> </body> Count-down Timer: <head> <script language="javascript" type="text/javascript"> var counter = 20; var timer = null; function countdown() { var outputField = document.getElementById("output"); outputField.innerHTML = counter + " seconds"; counter--; if (counter >= 0) timer = window.setTimeout("countdown()", 1000); else { alert('Lift-Off'); counter = 20; } } function stop_countdown() { window.clearTimeout(timer); alert("Countdown interrupted");
    • } </script> </head> <body> <h1>Countdown</h1> <p>Count: <span id="output"></span></p> <form> <input type="button" value="Countdown" onclick="countdown()" /> <input type="button" value="Emergency Stop" onclick="stop_countdown()" /> </form> </body> Falling Body Simulation As an application of timers, let’s create three programs to simulate what happens when a ball is dropped from a large height, like 10,000 m. The first simulation will assume that there is no force other than gravity and use the standard calculus solution where: , so that and , so that Simulation 1: Drop a ball, no air reistance, Calculus solution <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta content="text/html; charset=utf-8" http-equiv="Content-Type" /> <title>Gravity (no air, calculus)</title> <script language="javascript" type="text/javascript"> var timer = null; var init_height = 10000; var delta_t = 0.1; var g = 9.98; var t = 0; var height = init_height; var speed = 0; function drop() { t = t+ delta_t; speed = -g*t; height = init_height - 0.5*g*t*t; var timeField = document.getElementById("time"); var heightField = document.getElementById("height"); var speedField = document.getElementById("speed");
    • timeField.innerHTML = t; heightField.innerHTML = height; speedField.innerHTML = speed; if (height >= 0) timer = window.setTimeout("drop()", delta_t*1000); else alert("Hit the ground"); } </script> </head> <body> <h1>Gravity (no air, calculus)</h1> <p>Press the <tt>drop</tt> button to simulate the drop of a ball from a height of 10 km <i>without</i> air resistance. The values are updated every 0.1 seconds.</p> <h3>Calculus</h3> <ul> <li>Time: <span id="time">0</span> sec.</li> <li>Height: <span id="height">10000</span> meter</li> <li>Speed: <span id="speed">0</span> meter/second</li> </ul> <form> <input type="button" value="Drop" onclick="drop()" /> </form> </body> </html> The second simulation uses the same assumption of gravity being the only force acting on the ball, but instead of using the integrated solutions for and it uses iterative formulas: so that or and similarly so that If you look closely, the only real difference to the previous problem are the two lines that calculate the height and the speed of the ball. Simulation 2: drop a ball, no air resistance, simulation <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta content="text/html; charset=utf-8" http-equiv="Content-Type" /> <title>Gravity (no air, simulation)</title> <script language="javascript" type="text/javascript"> var timer = null;
    • var init_height = 10000; var delta_t = 0.1; var g = 9.98; var t = 0; var height = init_height; var speed = 0; function drop() { t = t + delta_t; speed = speed - g*delta_t; height = height + speed*delta_t; var timeField = document.getElementById("time"); var heightField = document.getElementById("height"); var speedField = document.getElementById("speed"); timeField.innerHTML = t; heightField.innerHTML = height; speedField.innerHTML = speed; if (height >= 0) timer = window.setTimeout("drop()", delta_t*1000); else alert("Hit the ground"); } </script> </head> <body> <h1>Gravity (no air, simulation)</h1> <p>Press the <tt>drop</tt> button to simulate the drop of a ball from a height of 10 km <i>without</i> air resistance. The values are updated every 0.1 seconds.</p> <h3>Simulation</h3> <ul> <li>Time: <span id="time">0</span> sec.</li> <li>Height: <span id="height">10000</span> meter</li> <li>Speed: <span id="speed">0</span> meter/second</li> </ul> <form> <input type="button" value="Drop" onclick="drop()" /> </form> </body> </html> The third simulation uses the assumption that the force downwards exerted by gravity is counteracted in part by an upwards force due to air resistance. In fact, air resistance is proportional to the speed the object is falling, so that: which can no longer be integrated easily (note that v is negative so that the above quantities actually have opposite signs). Thus, our only solution is to use an iterative simulation as in our previous case so that:
    • and Again, that really changes only two lines for our third and much more realistic solution: Simulation 3: drop a ball with air resistance, simulation <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta content="text/html; charset=utf-8" http-equiv="Content-Type" /> <title>Gravity (with air, simulation)</title> <script language="javascript" type="text/javascript"> var timer = null; var init_height = 10000; var delta_t = 0.1; var g = 9.98; var k = 0.5; var t = 0; var height = init_height; var speed = 0; function drop() { t = t + delta_t; speed = speed - (g + k*speed)*delta_t; height = height + speed*delta_t; var timeField = document.getElementById("time"); var heightField = document.getElementById("height"); var speedField = document.getElementById("speed"); timeField.innerHTML = t; heightField.innerHTML = height; speedField.innerHTML = speed; if (height >= 0) timer = window.setTimeout("drop()", delta_t*1000); else alert("Hit the ground"); } </script> </head> <body> <h1>Gravity (with air, simulation)</h1> <p>Press the <tt>drop</tt> button to simulate the drop of a ball from a height of 10 km <i>with</i> air resistance. The values are updated every 0.1 seconds.</p> <p>The acceleration acting on the ball are gravity, pointing down, and air resistance, pointing up. Gravity is constant while air resistance is proportional to the current speed. </p> <h3>Simulation</h3> <ul> <li>Time: <span id="time">0</span> sec.</li>
    • <li>Height: <span id="height">10000</span> meter</li> <li>Speed: <span id="speed">0</span> meter/second</li> </ul> <form> <input type="button" value="Drop" onclick="drop()" /> </form> </body> </html> If you run these simulations you should see that in the first two cases our ball hits the ground at very high speeds. In fact, our ball gets faster and faster and faster, which is no realistic. The third simulation, on the other hand, will show that the ball eventually reaches a “terminal velocity”, because at that speed the force due to air resistance will exactly counter-balance the force of gravity. XML and the XMLHttpRequest Object At the heart of most data-oriented Web 2.0 pages like Google Maps or Facebook lies the XMLHttpRequest. It lets you load data in a web page (a) without reloading the page and (b) synchronously or asynchronously. It does have some limitations: • IE 7, IE 8, and Firefox 2 and above handle XMLHttpRequest similarly • IE 5 and IE 6 handle XMLHttpRequest differently • Really old browsers do not handle XMLHttpRequest at all • XMLHttpRequest can only load data from the same server it is coming from • XMLHttpRequest cannot load data from a local disk at all We will cover the XMLHttpResponse object and its capabilities next time.