Está en la página 1de 34

Client-Side Scripting

Up to now we focused on implementing application logic on the

server The browser was just a simple, generalized user interface that did not play a role in executing the application logic It is beneficial for clients to share in the execution of some of the application logic Central focus of client-side scripting is to manipulate the content of a web page Application logic as such is not concerned with presentation, but client-side scripting can be used to make web pages more dynamic

Client-Side Application Logic

Field and form validation o For example, a date entry field should never accept the date Feb 30 o Without client-side validation this value would be submitted with the form and only there identified as an incorrect value o Relying solely on server-side validation is expensive (server trips) Automatic computation of dependent values o For example, when an item is added to a shopping cart, the new total can be computed automatically on the client

Making Web Pages More Dynamic

New input controls o For example, a date-picker control that pops up a calendar for the user to select a date from Rollovers and swaps o For example, as the mouse moves over an image it is replaced by another image that gives feedback to the user that the image can be clicked Adding HTML to the page o For example, a client-side script can insert the current date into a web page dynamically

Document Object Model

Regardless of the scripting language, the Document Object Model (DOM) provides a platform-neutral interface to browser and content of a page Defined by the W3C Most browsers implement it in their latest versions The name Document Object Model was chosen, because it provides an object interface to HTML (and XML) documents (data and behavior)

Object Interface to the Browser


For example, this is the set of browser objects Netscape makes available. A good reference on DOM programming.

JavaScript

Most common scripting technology in browsers available today Name a misnomer: JavaScript was born as "LiveScript" and its name was changed for marketing purposes However, it does share some basic syntax with Java, which makes it easy to learn o JavaScript does not have Java's typing system o Fewer core data types o Prototype-based object model (does not support inheritance)

Predefined JavaScript Objects


The principal object to use when working with document content is the document object, a reference to which can be obtained through the window object that represents a browser window For example, the following code initializes a text field in a form with the current day of the week
var today = new Date(); var weekdays = new Array("Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"); var dayOfWeek = weekdays[today.getDay()]; window.document.forms["demo"].elements["day"].value = dayOfWeek;

The Navigator Object


The navigator object indicates which browser we are using. function navProperties() { alert("The browser is: "+navigator.appName + "\n" + "The version number is: " + navigator.appVersion + "\n"); }

Browser?

Including JavaScript on a Web Page


Use the <script> tag to define regions of JavaScript code Generally, the <script> tag appears in the head of a web page; if it appears elsewhere it will be executed at this point in the document
o o

<script language="JavaScript"> function inRange(value, low, high) { return low <= value && value <= high; } function checkAge(field) { if (!inRange(field.value, 18, 99)) { alert("Enter a correct age!"); } } </script> Check Age

Events
Normal way of invoking JavaScript is in response to interface events
o <input type="text" name="age" onChange="checkAge(this);">

An event is something that triggers a script The event handler parameter of the HTML element defines the code (usually a call to a function) that will handle the event when it is fired o Some of the more common events are: onClick -- User clicks a form field or link onChange -- User changes the value of a form field onMouseOver -- User moves mouse pointer over a link onMouseOut -- User moves mouse out of an image or link onSubmit -- User submits a form
o o

Simple Temperature Calculator


o

The following code converts from Fahrenheit to Celsius

function convert(form) { form.celsius.value = Math.round((form.fahrenheit.value - 32)/1.8); }

Include it between <script> tags in the head of your web page, and insert the following somehwere in the body
o <form name="f2c"> Temperature: <input type="text" name="fahrenheit" value="32"> F to <input type="text" name="celsius"> C <input type="button" value="Convert" onClick="convert(this.form)"> </form>

Convert Temperature

How to Rollover?

A rollover swaps one image for another as the user moves over an image In the following code we refer to the image by its name (order) The onMouseOver handler sets the "src" property of the image to another value The onMouseOut handle resets the "src" property to its original value
o <a href="checkout.html" onMouseOver="images.order.src='rollover-2.jpg'" onMouseOut="images.order.src='rollover-1.jpg'"> <image name="order" src="rollover-1.jpg" border="0"> </a>

Rollover

Input Validation
o

Restrictions on a form Some fields may only accept numbers Others may only accept dates Some fields may only accept a range of entries Some fields may be required Some combination of fields may not be permitted Handle restrictions by two types of checks Validate each element as data is entered Perform validation when the form is submitted

Validating Form Elements


Checking element when data is entered most effective for validating format or range o Perform such checks using the onChange event handler
o <input type="text" name="age" onChange="checkAge(this);"

Validating Form Submissions


o o

Perform data validation just before form is submitted Perform such checks using the onSubmit event handler

<form method="post" action="/cgi/register.cgi" onSubmit="return checkForm(this);"> o

onSubmit handler must return true or false If it returns false, the form will not be submitted

function checkForm(form) { if (form.age.value == "") { alert("Please enter your age"); return false; } return true; } o

Note that the following are equivalent

form.age.value form["age"].value

Some Useful Validation Idioms


o o o o

Checking for integers Checking for ranges Checking for phone numbers Checking for postal codes

Checking for Integers


o

Checks if a value is an integer

function isInteger(value) { return value == parseInt(value); }

If the value contains other characters than numbers, parseInt() will be different from value
o

Checking for Ranges


o

Checks if a value is within a range

function inRange(value, low, high) { return low <= value && value <= high; } o

Obvious!

Checking for Phone Numbers


Since there are many ways phone numbers can be formatted, this is just an example
o function checkPhone(field) { if (!field.value.match(/\d{3}-\d{4}/)) { alert("Incorrect phone number"); return false; } return true; } o

This examples uses a regular expression to describe a phone

number

Checking for Postal Codes


o

Checks if a postal code is correctly formatted

function checkPostalCode(field) { if (!field.value.match(/([A-Z][0-9]){3}/)) { alert("Incorrect postal code"); return false; } return true; } o

Similar to checking a phone number

Examples
o

All examples

Day of Week
Add new appointment for:

Events
How old are you?

Temperature Converter
Temperature: F to C

Rollover

Input Validation
Phone: Postal Code:

Topics

Basics Primitives, Operations and Expressions Screen Output Control Statements Object Creation Arrays, Functions

JavaScript Basics
Collection of objects supporting control of browser and user interaction. Can be used on server too, but it is different there. Not studied here Isn't typed like Java -- more like Perl. Variables are dynamically bound at run time.

Similar syntax to Java ... but don't be fooled! Used instead of Applets because: o Easier to learn, graphics are simpler o Simple event model using callbacks o Applets downloaded separately to HTML

JavaScript Objects
Objects have collections of properties (members in Java or C++). Properties are data or method. Data either primitive or reference to object. Properties referenced by <object>.<property;> e.g. myCar.engine Javascript objects appear as Perl hashes: internally and externally Identifiers are CASE SENSITIVE: Foo and foo are different variable names.

Using JavaScript
Using <script> tag in head and body of HTML. Can write JavaScript inline or reference files externally. Internally <script language="JavaScript"> function testValue(field) { if (field.value < 0) { alert("Negative value!); } } </script> Externally <script language="JavaScript" src="test_value.js"></script>

JavaScript Keywords and Comments


break case catch continue default

delete do else finally for

function if in instanceof new

return switch this throw try

typeof var void while with

Comments have two forms: // and /* */ combination.

Hide code from browsers without JavaScript using: <!-- ... //--> Semi-colons are optional in most cases, but use them anyway!

JavaScript Primitive Types


Number -- double precision floating point String -- use ' or " for delimeter, use \ to create escape sequences. No difference between ' and "" forms. Boolean -- true or false Undefined -- single value undefined Null -- single value null

JavaScript Objects and Variables


Number String Boolean Wrappers for primitive types but define methods on them. Variable declared with var keyword.
var birthday = "8th March", index;

Interpreter does coercion.

JavaScript Operators and Assignment


Usual +, -, /, * Increment (++), Decrement (--) both pre- and postfix. Normal precendence rules apply. Testing type: typeof operator, returns "number", "string" or "boolean". Assignment exactly as Java e.g. var a += 4

Math and Number Objects

Math provides collection of methods to operate on Number objects


o

e.g. max, min, floor, sin, cos ... Number provides several useful constants: MAX_VALUE Largest representable number MIN_VALUE Smallest representable number

NaN Not a number POSITIVE_INFINITY Special value to represent infinity NEGATIVE_INFINITY Special value to represent negative infinity PI 3.14159265358979323846 approximately NaN != NaN (Use isNaN() to test). Useful method toString() on Number, although coercion often automatic.

Strings

Concatentation: "first" + "time" -> "firsttime" Length of a string:


var str = "Birthday"; var len = str.length;

charAt(N) indexOf(C) substring(I,J) toLowerCase toUpperCase

Returns character at N Position in string of character C Substring from Ith to Jth characters Converts to lower case Converts to upper case

Screen Output
JavaScript interpreted as body of HTML document is interpreted. Output from JavaScript goes to same place as HTML document. Use Document object (see DOM) A good reference on DOM programming. Use write method of document object: document.write("Hello world<br/>"); Can include ANY HTML in write method -- don't use \n Window object can generate dialog boxes: alert("Warning something bad has happened."); Alert var question = confirm("Do you want to continue?"); Confirm var birthday = prompt("What is your birthday?", "8th March"); Prompt Dialogs are modal

Compound Statements and Relational Expressions

Compound statements: statements delimited by { }. Operation Operator

Is equal to Is not equal to Is less (or equal) than (to) Is greater (or equal) than (to) Is strictly equal to Is strictly not equal to

== != <,<= >, >= === !==

Also have the use AND (&&), OR (||) and NOT (!)

Selection and Control Statements


if-then and if-then-else


if (birthday != "8th March) ... if (a > b) { a = b; } else { a += 1; }

switch
switch (expression) { case value_1: // value_1 statements case value_2: // value_2 statements ... default: // default statements // Optional }

Should use break at the end of value statements.

Selection Example
<html> <head> <title>A switch statement</title> </head> <body> <script language="JavaScript"> var case = 3; switch (4 * case - 10) { case 1: document.write("It's case 1", "<br/>"); break; case 2: document.write("It's case 2", "<br/>"); break;

case 3: document.write("It's case 3", "<br/>"); break; default: document.write("Error in switch statement, "<br/>"); break; } </script> </body> </html> Switch

Loops and While statements


while (control expression) { statements }


var index = 0; while (index < 10) { index++; ... }

for (initial expression; control expression; increment expression) { statements }


var sum = 0, count; for (count = 0; count <= 10; count++) { sum += count; }

do { statements } while ( control expression)


do { count++; sum = sum + (sum * count); } while (count <= 50);

Object Creation and Modification


Use new expression for creation of objects


var my_new_object = new Object();

my_new_object has no properties initially. Can create properties by assigning them. Object is a hash ... just like Perl
var my_car = new Object(); my_car.make = "Ford"; my_car.model = "Focus"; my_car.year = 2002; my_car.engine = new Object();

my_car.engine.size = "2.0L"; my_car.engine.hp = 124;

Can also access my_car.make by my_car["make"]. Delete properties by:


delete my_car.model;

Can also use constructors to generate "types". Can iterate on properties (just like Perl's foreach):
for (identifier in object) { statements } for (var prop in my_car) { document.write("Name: " + prop + "; Value: " + my_car[prop] + "<br/>"); }

Arrays

Have dynamic length Creation:


var my_array = new Array(1, 2, "three", "four"); var my_other_array = new Array(100); var my_third_array = [1, 2, "three", "four"];

Array bounds start at zero. my_array.length; // gives me the current length of my_array my_array.length = 100; // makes the current length of my_array 100 my_array.join(" : ") would yield "1 : 2 : three : four" my_array.reverse() would yield ["four", "three", 2 1] Also have sort()
var names = ["Bill", "Ben", "Alice", "Tony"]; var sorted_names = names.sorted(); sorted_names == ["Alice", "Ben", "Bill", "Tony"];

Can pass (2 argument) function to sorted(sort_fn)


// Sort descending function sort_fn(a, b) {b - a}; sorted_names = names.sort(sort_fn); sorted_names == ["Tony", "Bill", "Ben", "Alice"];

And slice()?
var slice_of_names = names.slice(1,3); slice_of_names == ["Ben", "Alice", "Tony"]; slice_of_names = names.slice(2); slice_of_names == ["Alice", "Tony"];

Array Operations
to to

push() and pop()


var popped_name = names.pop(); popped_name == "Tony"; // Removed Tony from the list names.push("Tony"); names == ["Bill", "Ben", "Alice", "Tony"]; // Added Tony end of list

shift() and unshift()


var shifted_name = names.shift(); shifted_name == "Bill"; // Removed Bill from the list names.unshift("Bill"); names == ["Bill", "Ben", "Alice", "Tony"]; // Added Bill front of list

Multidimensional Arrays

Implemented as array of arrays


var nested_array = [[1, 2, 3], [4, 5, 6], [7, 8, 9]];

Functions
Using "function" keyword Can have references to functions too. function foo(arg1, arg2) { var function_name = "foo"; current_function = function_name; document.write("This is the " + function_name + " function. <br/>";); } var reference2foo = foo; // Can call foo via reference now reference2foo(); Have to define function before refering to it. Functions go in <head> section of document.

Functions

Functions can have local variables; e.g. function_name

NOTE: Implicitly declared variables are GLOBAL; e.g. current_function Local variables of same name take precedence over global declarations. Parameter passing is by value, but objects are references! Parameters communicated via arguments array -- actual as well as formal. arguments array is similiar to @_ in Perl.
foo(1, 2, 3); // Formal are 1 and 2, arguments array is [1, 2, 3] foo(1); // Formal is 1, arguments array is [1]

Constructors
You can use "new Object()" and assign properties, but it's awkward. Constructors are special functions for creating and initializing objects.
function car(new_make, new_model, new_year) { this.make = new_make; this.model = new_model; this.year = new_year; } // Constructing a car var my_car = new car("Saturn", "SL1", "2002"); Can have method as well as data properties. function display_car() { document.write("Car make: ", this.make, "<br/>"); document.write("Car model: ", this.model, "<br/>"); document.write("Car year: ", this.year, "<br/>"); } // Now constructor is: function car(new_make, new_model, new_year) { // Data properties this.make = new_make; this.model = new_model; this.year = new_year; // Method properties this.display = display_car; // <-- Method to display myself } // Display myself var my_car = new car("Saturn", "SL1", "2002");

// Display the car on the current page my_car.display();

Pattern Matching

Applies to String objects. Similiar principles to Perl. search method


var str = "Saturn"; var position = str.search(/ur/); // Would return 3

replace method
var str = "Fred, Freddie, and Frederica were siblings"; str.replace(/Fre/g, "Boy"); // str == "Boyd, Boyddie, and Boyderica were siblings"; // $1, $2, and $3 variables are set to "Fre"

match method
var str = "I can have 1 2 3 or 4 chances to win." var matches = str.match(/\d/g); // matches == [1, 2, 3, 4]

split method
var str = "pears:grapes:apples"; var fruit = str.split(/:/); // fruit == [pears, grapes, apples]

Regular expressions same as perl; e.g.


\s for space \d for [0,1,2,3,4,5,6,7,8,9] etc

Topics

Document Object Model (review) Events and event handling Events, attributes and tags Load and unloading documents Button events Event propagation

Document Object Model (DOM)


DOM standardized by W3C. Defines object hierarchy to allow scripts to interact with HTML documents. DOM is just an interface between HTML and application programs. DOM is tree-like, but it's an abstract interface. Most browsers versions beyond 5 (IE, Netscape) support DOM. The document object represents displayed HTML document. The window object is container for document object.
Important objects within document:

forms Forms defined within the HTML document forms.elements Objects within the form; e.g. buttons and menus

DOM Structure example


<table> <tr> <td>a</td> <td>b</td> </tr> <tr> <td>c</td> <td>d</td> </tr> </table>

Events

JavaScript implements an event-driven programming model. Events are notifications of something noteworthy happening: o Document loading or unloading o Clicking a button o Changing focus from one element to another Events are processed by event handlers. Similiar to, but simpler than, Java model. Events are objects, so names are case-sensitive. Don't use the document.write() method in event handlers! Tag Attribute Explanation onAbort Image loading aborted 1. A document or frame loses input focus onBlur 2. Text or selection element loses focus 1. Text field or area changes and loses focus onChange 2. Selection element changes and loses focus 1. Click on link 2. Submit, Reset or other Button is pressed 3. Radio button is pressed onClick 4. Checkbox is clicked 1. Image loading error 2. Document loading error 3. Frame loading error 1. Document or frame receives focus 2. Text field or area receives focus 3. Select element receives focus 1. Image has been loaded

Event abort blur

change

click

error

onError

focus

onFocus

load

onLoad 2. Document or frame has been loaded 1. Mouse moved from over link

mouseout

onMouseOut 2. Mouse moved out of image map 1. Mouse moved over link

mouseover onMouseOver reset resize onReset onResize 2. Mouse moved into image map Reset button pressed Window size is changed

1. Mouse cursor moved over text field select submit unload onSelect onSubmit onUnload 2. User exits a frameset 2. Text area is selected within a text area Submit button is pressed 1. User exits the document

Element Identification and Event Callbacks


Give every element and id attribute. Use getElementById method of document to obtain element. ... <form id = "testExample"> <input type="text" id = "testInput"> ... </form> ... document.getElementById("testInput").style is address of input element Callbacks specified in 2 ways: Assume form with name "example" defined, containing "textField" As attribute of HTML tag: <input type="text" name="textField" value="2002" onChange="validate()"> Or dynamically, through property of element: document.forms["example"].elements["textField"].onChange = validate; Using event attribute (e.g. onChange) adds flexibility. Cannot pass arguments through -- not even "this".

Selection and Focus


Error handling frequently requires change of focus and selection. Invoke function through address of DOM element document.forms["example"].elements["textField"].focus(); // Sets focus

document.forms["example"].elements["textField"].select() // Highlight text

Remember: if form to remain active return false after check.

Event Propagation

Can handle events on one element by another Document can handle ALL onchange events (for example) Table could handle ALL onchange events for its cells load, unload, focus and blur events do not propagate

Dynamic Content
DHTML examples Can modify DOM tree dynamically. Addition, deletion and editing possible e.g. Adding TEXT function appendTEXT(tag,index,text){ var oj = document.createTextNode(text) ; document.getElementsByTagName(tag).item(index).appen dChild(oj); } <FORM> <INPUT TYPE="button" VALUE=" to DIV0" onClick="if(document.getElementById)appendTEXT('D IV',0,' (^^)/DIV0 ')"> <INPUT TYPE="button" VALUE=" to DIV1" onClick="if(document.getElementById)appendTEXT('D IV',1,' (^^)/DIV1 ')"> <INPUT TYPE="button" VALUE=" to DIV2" onClick="if(document.getElementById)appendTEXT('D IV',2,' (^^)/DIV2 ')"> <INPUT TYPE="button" VALUE=" to SPAN0" onClick="if(document.getElementById)appendTEXT('S PAN',0,' (^^)/SPAN0 ')"> <INPUT TYPE="button" VALUE=" to SPAN1" onClick="if(document.getElementById)appendTEXT('S PAN',1,' (^^)/SPAN1 ')">

</FORM> <DIV>div0 : <SPAN>span1 <DIV>div1 : <DIV>div2 : </form>

<SPAN>span0 : </SPAN></DIV> : </SPAN> </DIV> </DIV>

div0 : span0 : span1 : div1 : div2 :

Adding an Image function addImage(imageURL) { var imgEl = document.createElement("IMG"); imgEl.src = imageURL; imgEl.id = imageURL; document.body.appendChild(imgEl); } <a href="javascript:addImage('rollover.jpg'); void 0">Adding an Image</a>

Adding an Image
Edit the image function editImage(id, src) { var imgEl = document.getElementById(id); imgEl.src = src; // Should re-do the size of the image -- exercise to student } <a href="javascript:editImage('rollover.jpg', 'dom.jpg'); void 0">Editing an Image</a>

Editing an Image

Removing the image


function removeImage(id) { var imgEl = document.getElementById(id); document.body.removeChild(imgEl); }

<a href="javascript:removeImage('rollover.jpg'); void 0">Removing an Image</a>

Remove an Image

Dynamic Positioning and Visibility


visible and hidden attributes values used to change display. Attibute visibility can be accessed document.getElementById("id").visibility = "visible" | "hidden"; <form id = "dynamicForm"> <span id="dynamicText">Text field: </span> <input type="text" id = "dynamicInput" value="8th March"> </form>

Text field: Hide form <a href="javascript:document.getElementById('dynamicForm').style.visibility ='hidden'; void 0">Hide form</a> Show form <a href="javascript:document.getElementById('dynamicForm').style.visibility ='visible'; void 0">Show form</a>

Positioning: top and left attributes


function moveIt(id, newTop, newLeft) { var elt = document.getElementById(id); elt.top = newTop; elt.left = newLeft; }

Cookies
Can be created on the client side too. DOM exposes cookie through document.cookie Set a cookie by assigning property, retrieve one by reading its current value. The following statement, for example, sets a new cookie with a minimum number of attributes:

document.cookie = "cookieName=cookieValue"; Set Cookie Display the property's value: alert(document.cookie);

Value of document.cookie is string containing a list of all cookies associated with web page. Consists of name=value pairs for each cookie that matches the current domain, path, and date.
cookieName1=cookieValue1; cookieName2=cookieValue2

Cookie Manipulation Functions


// name - name of the cookie // value - value of the cookie // [expires] - expiration date of the cookie (defaults to end of current session) // [path] - path for which the cookie is valid (defaults to path of calling document) // [domain] - domain for which the cookie is valid (defaults to domain of calling document) // [secure] - Boolean value indicating if the cookie transmission requires a secure transmission // * an argument defaults when it is assigned null as a placeholder // * a null placeholder is not required for trailing omitted arguments // E.G. document.cookie = "cookieName=cookieValue; expires=Thu, 01-Jan-70 00:00:01 GMT; path=/directory/thisFile.html; domain=scs.carleton.ca; secure function setCookie(name, value, expires, path, domain, secure) { var curCookie = name + "=" + escape(value) + ((expires) ? "; expires=" + expires.toGMTString() : "") + ((path) ? "; path=" + path : "") + ((domain) ? "; domain=" + domain : "") + ((secure) ? "; secure" : ""); document.cookie = curCookie; } // name - name of the desired cookie // * return string containing value of specified cookie or null if cookie does not exist function getCookie(name) { var dc = document.cookie; var prefix = name + "="; var begin = dc.indexOf("; " + prefix); if (begin == -1) { begin = dc.indexOf(prefix); if (begin != 0) return null; } else

begin += 2; var end = document.cookie.indexOf(";", begin); if (end == -1) end = dc.length; return unescape(dc.substring(begin + prefix.length, end));

// name - name of the cookie // [path] - path of the cookie (must be same as path used to create cookie) // [domain] - domain of the cookie (must be same as domain used to create cookie) // * path and donavigator.mimeTypesdoublemain default if assigned null or omitted if no explicit argument proceeds // Sets the expiry date so that the cookie will disappear immediately. function deleteCookie(name, path, domain) { if (getCookie(name)) { document.cookie = name + "=" + ((path) ? "; path=" + path : "") + ((domain) ? "; domain=" + domain : "") + "; expires=Thu, 01-Jan-70 00:00:01 GMT"; } }

Cookie Manipulation Example -- personalized counter


// date - any instance of the Date object // * hand all instances of the Date object to this function for "repairs" function fixDate(date) { var base = new Date(0); var skew = base.getTime(); if (skew > 0) date.setTime(date.getTime() - skew); } // create an instance of the Date object var now = new Date(); // fix the bug in Navigator 2.0, Macintosh fixDate(now); // cookie expires in one year (actually, 365 days) // 365 days in a year // 24 hours in a day // 60 minutes in an hour // 60 seconds in a minute // 1000 milliseconds in a second now.setTime(now.getTime() + 365 * 24 * 60 * 60 * 1000); var visits = getCookie("counter"); // if the cookie wasn't found, this is your first visit

if (!visits) { visits = 1; // the value for the new cookie document.write("<span style=color:red>By the way, this is your first time here.</span>"); } else { // increment the counter visits = parseInt(visits) + 1; document.write("<span style=\"color:red\">By the way, you have been here <i>" + visits + "</i> times.</span>"); } // set the new cookie setCookie("counter", visits, now);

By the way, this is your first time here.

Breaking out of Frames


<!-- frame buster - code by Gordon McComb --> <script language="JavaScript" type="text/javascript"> <!-- Hide script from older browsers setTimeout ("changePage()", 3000); function changePage() { if (self.parent.frames.length != 0) self.parent.location=document.location; } // end hiding contents --> </script>

Showing modification dates


<script language="JavaScript" type="text/javascript"> <!-document.write("Last Modified " + document.lastModified) // --> </script>

Has it changed?

Useful to know if a page has changed since last visit.


<script language="JavaScript" type="text/javascript"> <!-var lastModified = getCookie("lastModified"); if (lastModified != document.lastModified) {

if (lastModified) { document.write("Document changed since last visit"); } // create an instance of the Date object var now = new Date(); // fix the bug in Navigator 2.0, Macintosh fixDate(now); // cookie expires in one year (actually, 365 days) // 365 days in a year // 24 hours in a day // 60 minutes in an hour // 60 seconds in a minute // 1000 milliseconds in a second now.setTime(now.getTime() + 365 * 24 * 60 * 60 * 1000); setCookie("lastModified", document.lastModified, now); } // --> >/script> Document changed since last visit

Bookmarklets
URLs with JavaScript code that have been saved as bookmarks o http://www.bookmarklets.com How you turn an URL into a bookmark is browser-specific, for example o Right-click and choose to save link as bookmark o Left-drag to personal toolbar Your first bookmarklet
javascript:void(window.open(''))

Open window

<a href="javascript:void(window.open(''))">Open window</a>

Using void() ensures that the original page is unchanged

Example - Integrating an Online Dictionary

Create your own bookmarklet that looks up a word you have selected on your page on the Merriam-Webster web site
javascript:q=document.selection.createRange().text;location.href ='http://www.m-w.com/cgi-bin/dictionary? book=Dictionary&va='+escape(q); void(0)

How did we know this? Look at the form on the web site

<FORM name="dict" method="post" action="/cgi-bin/dictionary"> <TD valign="middle" width="165"> <INPUT type="hidden" name="book" value="Dictionary"> <FONT color="#ffffff" size="2" face="Arial, Helvetica"><B>Collegiate<SUP></SUP> Dictionary</B></FONT> </TD><TD valign="middle" width="140"> <INPUT name="va" size="15"> </TD><TD valign="middle" width="95"> <INPUT type="submit" value="Look it up"> </TD> </FORM>

Lookup in Webster

<a href="javascript:q=document.selection.createRange().text;location .href='http://www.m-w.com/cgi-bin/dictionary? book=Dictionary&va='+escape(q);void(0)">Lookup in Webster</a>

Example - Integrating an Online Search


Create your own bookmarklet that looks up a word you have selected on your page using Google

Google Search

<a href="javascript:q=document.selection.createRange().text;location .href='http://www.google.ca/search?q='+escape(q)+'&ie=UTF8&oe=UTF-8&hl=en&meta=';void(0)">Google Search&Lt;/a>

Bookmarklets and CGI

Recap
o

Bookmarklets are JavaScripts saved as bookmarks

Execute in the browser's frontmost window Can interact with object or data in this window Example o Create and store comments on web pages o Retrieve them later when you visit the pages again
o o

Example - CGI

Accepts an URL and a comment and records them Retrieves a comment when given an URL Declarations

#!/usr/bin/perl use CGI; use CGI::Carp( fatalsToBrowser ); my $scriptUrl = "http://localhost/~mrw/cgi-bin/245/comment.cgi"; my $q = new CGI; my $url = $q->param("url"); my $comment;

Example - CGI

Branch off to the appropriate handler

if ($q->param("save")) { $comment = $q->param("comment") || ""; saveComment($url, $comment); } else { $comment = getComment($url); }

Example - CGI

Generate a comment form

print $q->header("text/html"), $q->start_html(-title => $url, -bgcolor => "yellow"), $q->start_form({ action => $scriptUrl }), $q->hidden("url"), # inherits value $q->textarea(-name => "comment", -cols => 30,

$q->p(

-rows => 8, -value => $comment, -wrap),

$q->submit(-name => "save", -value => "Save Comment")), $q->end_form, $q->end_html;

Example -CGI

Retrieve a comment from the database

sub getComment { my $url = shift; my %db; dbmopen(%db, "comment_db", 0666) || die "unable to open comment database"; requestLock("comment_db"), my $comment = $db{$url}; releaseLock("comment_db"), dbmclose(%db); return $comment; }

Example - CGI

Save a comment to the database

sub saveComment { my ($url, $comment) = @_; my %db; dbmopen(%db, "comment_db", 0666) || die "unable to open comment database"; requestLock("comment_db"), $db{$url} = $comment; releaseLock("comment_db"), dbmclose(%db); }

Example - JavaScript

JavaScript that invokes this CGI script

url = document.location.href; open('http://localhost/~me/205/bookmarklets/comments.cgi?url=' + escape(url), 'commentlet', 'width=400,height=250'); void(0);

Commentlet

<a href="javascript:url = document.location.href; open('http://localhost/~mrw/cgi-bin/245/comment.cgi?url=' + escape(url), 'commentlet', 'width=400,height=250'); void(0);">Commentlet</a>

Example - Usage

Visit a web site and select the bookmarklet Browser displays another window

Enter a comment and save it On returning to the page, the window will contain your original comment Comments can be shared with other users!

Example - Source Code

Here is the full source code of the CGI script

#!/usr/bin/perl

comment.cgi

use CGI; use CGI::Carp( fatalsToBrowser ); my $scriptUrl = "http://localhost/~mrw/cgi-bin/245/comment.cgi"; my $q = new CGI; my $url = $q->param("url"); my $comment; if ($q->param("save")) { $comment = $q->param("comment") || ""; saveComment($url, $comment); } else { $comment = getComment($url); } print $q->header("text/html"), $q->start_html(-title => $url, -bgcolor => "yellow"), $q->start_form({ action => $scriptUrl }), $q->hidden("url"), # inherits value $q->textarea(-name => "comment", -cols => 60, -rows => 14, -value => $comment, -wrap), $q->p( $q->submit(-name => "save", -value => "Save Comment")), $q->end_form, $q->end_html; sub getComment { my $url = shift; my %db; dbmopen(%db, "comment_db", 0666) || die "unable to open comment database"; requestLock("comment_db"), my $comment = $db{$url}; releaseLock("comment_db"), dbmclose(%db); return $comment; } sub saveComment { my ($url, $comment) = @_; my %db; dbmopen(%db, "comment_db", 0666) || die "unable to open comment database"; requestLock("comment_db"), $db{$url} = $comment; releaseLock("comment_db"),

dbmclose(%db);

# one of many ways to do this ... sub requestLock { my $alias = shift; my $n = 0; my $lock = $alias . ".lock"; while (mkdir($lock, 0555) == 0) { $! == $EEXIST || die "can't make $lock: $!"; $n++ < 30 || die "timed out waiting for $lock"; sleep(1); } } sub releaseLock { my $alias = shift; my $lock = $alias . ".lock"; rmdir($lock); }

También podría gustarte