As a scripting language, JavaScript can run in many
different environments.
An environment is just a bunch of global
variables/functions.
In the browser, the window object is the
global object. Everything client-side gets accessed
via this object.
Unfortunately, the structure of that object differs
between browsers, but there is a common subset.
1.1 Level 0 DOM
The Document
Object Model [3] (DOM) is a standardized object model for
representing HTML or XML.
The level 0 DOM is a non-standardized subset
which all browsers implement.
window; //The global object
//various other windows
window.self;
window.window;
window.parent;
window.top;
//navigator object
window.navigator;
//array of window objects
window.frames[];
//location object
window.location;
window.history;
window.screen;
//The document object (DOM)
window.document;
//Ways to access the various elements in a document
window.document.applets[];
window.document.images[];
window.document.links[];
window.document.anchors[];
window.document.forms[];
window.document.forms[].elements[];
window.document.forms[].elements[].options[];
1.2 Including JavaScript in HTML
The script tag loads JavaScript.
You can inline it or use the src attribute.
<html><head><title>The date</title><script language="JavaScript">
function printDate() {
var d = new Date();
document.write(d.toLocaleString());
}
</script></head><body><p>The date and time are:<br/><script language="JavaScript">
printDate();
</script></p></body></html>
/*
* This function parses ampersand-separated name=value argument pairs from
* the query string of the URL. It stores the name=value pairs in
* properties of an object and returns that object. Use it like this:
*
* var args = getArgs(); // Parse args from URL
* var q = args.q || ""; // Use argument, if defined, or a default value
* var n = args.n ? parseInt(args.n) : 10;
*/functiongetArgs() {
varargs = new Object();
varquery = location.search.substring(1); // Get query string
varpairs = query.split("&"); // Break at ampersand
for(vari = 0; i < pairs.length; i++) {
varpos = pairs[i].indexOf('='); // Look for "name=value"
if (pos == -1) continue; // If not found, skip
varargname = pairs[i].substring(0,pos); // Extract the name
varvalue = pairs[i].substring(pos+1); // Extract the value
value = decodeURIComponent(value); // Decode it, if needed
args[argname] = value; // Store as a property
}
return args; // Return the object
}
replace() does the same but deletes current
page from history: back button will not go to it.
2.3 Window Geometry
/**
* Geometry.js: portable functions for querying window and document geometry
*
* This module defines functions for querying window and document geometry.
*
* getWindowX/Y(): return the position of the window on the screen
* getViewportWidth/Height(): return the size of the browser viewport area
* getDocumentWidth/Height(): return the size of the document.
* getHorizontalScroll(): return the position of the horizontal scrollbar
* getVerticalScroll(): return the position of the vertical scrollbar
*
* Note that there is no portable way to query the overall size of the
* browser window, so there are no getWindowWidth/Height() functions.
*
* IMPORTANT: This module must be included in the <body> of a document
* instead of the <head> of the document.
*/varGeometry = {};
if (window.screenLeft) { // IE and others
Geometry.getWindowX = function() { return window.screenLeft; };
Geometry.getWindowY = function() { return window.screenTop; };
}
elseif (window.screenX) { // Firefox and others
Geometry.getWindowX = function() { return window.screenX; };
Geometry.getWindowY = function() { return window.screenY; };
}
if (window.innerWidth) { // All browsers but IE
Geometry.getViewportWidth = function() { return window.innerWidth; };
Geometry.getViewportHeight = function() { return window.innerHeight; };
Geometry.getHorizontalScroll = function() { return window.pageXOffset; };
Geometry.getVerticalScroll = function() { return window.pageYOffset; };
}
elseif (document.documentElement && document.documentElement.clientWidth) {
// These functions are for IE6 when there is a DOCTYPE
Geometry.getViewportWidth =
function() { return document.documentElement.clientWidth; };
Geometry.getViewportHeight =
function() { return document.documentElement.clientHeight; };
Geometry.getHorizontalScroll =
function() { return document.documentElement.scrollLeft; };
Geometry.getVerticalScroll =
function() { return document.documentElement.scrollTop; };
}
elseif (document.body.clientWidth) {
// These are for IE4, IE5, and IE6 without a DOCTYPE
Geometry.getViewportWidth =
function() { return document.body.clientWidth; };
Geometry.getViewportHeight =
function() { return document.body.clientHeight; };
Geometry.getHorizontalScroll =
function() { return document.body.scrollLeft; };
Geometry.getVerticalScroll =
function() { return document.body.scrollTop; };
}
window.open() [13]: but
only works in response to a user action.
var w = window.open('url of window to load', 'name for
window', 'width=400,height=350,resizable=no')
w.close()
w.focus() gives keyboard focus to w.
w.blur() takes it away
w.scrollBy(x) scrolls by x pixels.
w.scrollTo(x) scrolls to absolute position.
w.scrollIntoView()
2.6 Window Moving Example
varbounce = {
x:0, y:0, w:200, h:100, // Window position and size
dx:5, dy:5, // Window velocity
interval: 100, // Milliseconds between updates
win: null, // The window we will create
timer: null, // Return value of setInterval()
// Start the animation
start: function() {
// Start with the window in the center of the screen
bounce.x = (screen.width - bounce.w)/2;
bounce.y = (screen.height - bounce.h)/2;
// Create the window that we're going to move around
// The javascript: URL is simply a way to display a short document
// The final argument specifies the window size
bounce.win = window.open('javascript:"<h1>BOUNCE!</h1>"', "",
"left=" + bounce.x + ",top=" + bounce.y +
",width=" + bounce.w + ",height=" +bounce.h+
",status=yes");
// Use setInterval() to call the nextFrame() method every interval
// milliseconds. Store the return value so that we can stop the
// animation by passing it to clearInterval().
bounce.timer = setInterval(bounce.nextFrame, bounce.interval);
},
// Stop the animation
stop: function() {
clearInterval(bounce.timer); // Cancel timer
if (!bounce.win.closed) bounce.win.close(); // Close window
},
// Display the next frame of the animation. Invoked by setInterval()
nextFrame: function() {
// If the user closed the window, stop the animation
if (bounce.win.closed) {
clearInterval(bounce.timer);
return;
}
// Bounce if we have reached the right or left edge
if ((bounce.x+bounce.dx > (screen.availWidth - bounce.w)) ||
(bounce.x+bounce.dx < 0)) bounce.dx = -bounce.dx;
// Bounce if we have reached the bottom or top edge
if ((bounce.y+bounce.dy > (screen.availHeight - bounce.h)) ||
(bounce.y+bounce.dy < 0)) bounce.dy = -bounce.dy;
// Update the current position of the window
bounce.x += bounce.dx;
bounce.y += bounce.dy;
// Finally, move the window to the new position
bounce.win.moveTo(bounce.x,bounce.y);
// Display current position in window status line
bounce.win.defaultStatus = "(" + bounce.x + "," + bounce.y + ")";
}
}
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"><html><head><title></title><meta http-equiv="REFRESH" content="0;url=http://jmvidal.cse.sc.edu/webapps/spring08/"></head><body><h1>Web Applications</h1><p>
Redirecting to <a href="spring08/">Spring 2008 class</a>.
</p/><hr><address><a href="mailto:jmvidal@sc.edu">Jose M Vidal</a></address><!-- Created: Sat Nov 24 07:51:32 EST 2007 --><!-- hhmts start -->
Last modified: Sat Nov 24 07:52:57 EST 2007
<!-- hhmts end --></body></html>
functionlistlinks(d) {
// Open a new window
varnewwin = window.open("", "navwin",
"menubar=yes,scrollbars=yes,resizable=yes," +
"width=500,height=300");
// Give it a title
newwin.document.write("<h1>Navigation Window: " + d.title + "</h1>");
// List all links
for(vari = 0; i < d.links.length; i++) {
// For each link object, determine the text to display.
// First, try to get the text between <a> and </a> using a
// browser-dependent property. If none, use the name instead.
vara = d.links[i];
vartext = null;
if (a.text) text = a.text; // Netscape 4
elseif (a.innerText) text = a.innerText; // IE 4+
if ((text == null) || (text == '')) text = a.name; // Default
// Now output that text as a link. The href property of this link
// is never used: the onclick handler does the work, setting the
// location.hash property of the original window to make that
// window jump to display the named link. See Window.opener,
// Window.location and Location.hash, and Link.onclick.
newwin.document.write('<a href="#' + a.name + '"' +
' onclick="opener.location.hash=\'' + a.name +
'\'; return false;">');
newwin.document.write(text);
newwin.document.write('</a><br>');
}
newwin.document.close(); // Never forget to close the document!
}
functioncountTags(n) { // n is a Node
varnumtags = 0; // Initialize the tag counter
if (n.nodeType == 1 /*Node.ELEMENT_NODE*/) // Check if n is an Element
numtags++; // Increment the counter if so
varchildren = n.childNodes; // Now get all children of n
for(vari=0; i < children.length; i++) { // Loop through the children
numtags += countTags(children[i]); // Recurse on each one
}
return numtags; // Return the total
}
/**
* getText(n): Find all Text nodes at or beneath the node n.
* Concatenate their content and return it as a string.
*/functiongetText(n) {
// Repeated string concatenation can be inefficient, so we collect
// the value of all text nodes into an array, and then concatenate
// the elements of that array all at once.
varstrings = [];
getStrings(n, strings);
return strings.join("");
// This recursive function finds all text nodes and appends
// their text to an array.
functiongetStrings(n, strings) {
if (n.nodeType == 3 /* Node.TEXT_NODE */)
strings.push(n.data);
elseif ((n.nodeType == 1) || (n.nodeType == 9)) /* Node.ELEMENT_NODE or DOCUMENT*/ {
// Note iteration with firstChild/nextSibling
for(varm = n.firstChild; m != null; m = m.nextSibling) {
getStrings(m, strings);
}
}
}
}
document.getElementsByName('line') [26]
returns array of elements with the given name
attribute value. Does not seem to work with XHTML.
3.7 Modifying a Document
appendChild(n) adds a child node. If node is
already a child then it is moved to the end.
functionsortkids(e) {
// This is the element whose children we are going to sort
if (typeof e == "string") e = document.getElementById(e);
// Transfer the element (but not text node) children of e to a real array
varkids = [];
for(varx = e.firstChild; x != null; x = x.nextSibling)
if (x.nodeType == 1 /* Node.ELEMENT_NODE */) kids.push(x);
// Now sort the array based on the text content of each kid.
// Assume that each kid has only a single child and it is a Text node
kids.sort(function(n, m) { // This is the comparator function for sorting
vars = n.firstChild.data; // text of node n
vart = m.firstChild.data; // text of node m
if (s < t) return -1; // n comes before m
elseif (s > t) return 1; // n comes after m
elsereturn 0; // n and m are equal
});
// Now append the kids back into the parent in their sorted order.
// When we insert a node that is already part of the document, it is
// automatically removed from its current position, so reinserting
// these nodes automatically moves them from their old position
// Note that any text nodes we skipped get left behind, however.
for(vari = 0; i < kids.length; i++) e.appendChild(kids[i]);
}
// This function recursively looks at Node n and its descendants,
// converting all Text node data to uppercase
functionupcase(n) {
if (n.nodeType == 3 /*Node.TEXT_NODE*/) {
// If the node is a Text node, create a new Text node that
// holds the uppercase version of the node's text, and use the
// replaceChild() method of the parent node to replace the
// original node with the new uppercase node.
n.data = n.data.toUpperCase();
}
else {
// If the node is not a Text node, loop through its children
// and recursively call this function on each child.
varkids = n.childNodes;
for(vari = 0; i < kids.length; i++) upcase(kids[i]);
}
}
Create one with
document.createDocumentFragment().
For example:
// Reverse the order of the children of Node n
functionreverse(n) {
// Create an empty DocumentFragment as a temporary container
varf = document.createDocumentFragment();
// Now loop backward through the children, moving each one to the fragment.
// The last child of n becomes the first child of f, and vice-versa.
// Note that appending a child to f automatically removes it from n.
while(n.lastChild) f.appendChild(n.lastChild);
// Finally, move the children of f all at once back to n, all at once.
n.appendChild(f);
}
/**
* make(tagname, attributes, children):
* create an HTML element with specified tagname, attributes and children.
*
* The attributes argument is a JavaScript object: the names and values of its
* properties are taken as the names and values of the attributes to set.
* If attributes is null, and children is an array or a string, the attributes
* can be omitted altogether and the children passed as the second argument.
*
* The children argument is normally an array of children to be added to
* the created element. If there are no children, this argument can be
* omitted. If there is only a single child, it can be passed directly
* instead of being enclosed in an array. (But if the child is not a string
* and no attributes are specified, an array must be used.)
*
* Example: make("p", ["This is a ", make("b", "bold"), " word."]);
*
* Inspired by the MochiKit library (http://mochikit.com) by Bob Ippolito
*/functionmake(tagname, attributes, children) {
// If we were invoked with two arguments the attributes argument is
// an array or string, it should really be the children arguments.
if (arguments.length == 2 &&
(attributes instanceof Array || typeof attributes == "string")) {
children = attributes;
attributes = null;
}
// Create the element
vare = document.createElement(tagname);
// Set attributes
if (attributes) {
for(var name in attributes) e.setAttribute(name, attributes[name]);
}
// Add children, if any were specified.
if (children != null) {
if (children instanceof Array) { // If it really is an array
for(vari = 0; i < children.length; i++) { // Loop through kids
varchild = children[i];
if (typeof child == "string") // Handle text nodes
child = document.createTextNode(child);
e.appendChild(child); // Assume anything else is a Node
}
}
elseif (typeof children == "string") // Handle single text child
e.appendChild(document.createTextNode(children));
else e.appendChild(children); // Handle any other single child
}
// Finally, return the element.
return e;
}
/**
* maker(tagname): return a function that calls make() for the specified tag.
* Example: var table = maker("table"), tr = maker("tr"), td = maker("td");
*/functionmaker(tag) {
returnfunction(attrs, kids) {
if (arguments.length == 1) return make(tag, attrs);
elsereturn make(tag, attrs, kids);
}
}
functiongetSelectedText() {
if (window.getSelection) {
// This technique is the most likely to be standardized.
// getSelection() returns a Selection object, which we do not document.
return window.getSelection().toString();
}
elseif (document.getSelection) {
// This is an older, simpler technique that returns a string
return document.getSelection();
}
elseif (document.selection) {
// This is the IE-specific technique.
// We do not document the IE selection property or TextRange objects.
return document.selection.createRange().text;
}
}
position specifies the type of positioning to use:
static: default. According to normal flow
(left-to-right, top-to-bottom).
absolute: relative to containing
element.
fixed: relative to browser window. Does
not scroll.
relative: find its position using normal
flow then adjust relative to that position.
position: absolute; left: 10px; right 20px; top:
20%; bottom: 20%;
z-index: specifies stacking other (who is
visible).
visibility:
hidden but is laid out (space reserved).
visible
display: none makes it disappear completely
(back with block or inline)
opacity: .75: make transparent (CSS3: Firefox
only). Example.
filter: alpha(opacity=75): make transparent
(IE only)
overflow: what happens if all the text does not fit:
visible: write over the rest of
page.
hidden: hide extra.
scroll: put up a scroll bar.
auto: put up scroll bar but only if needed.
4.1.1 Shadows
/**
* Shadows.js: shadowed text with CSS.
*
* This module defines a single global object named Shadows.
* The properties of this object are two utility functions.
*
* Shadows.add(element, shadows):
* Add the specified shadows to the specified element. The first argument
* is a document element or element id. This element must have a single
* text node as its child. This child is the one that will be shadowed.
* Shadows are specified with a string argument whose syntax is explained
* below.
*
* Shadows.addAll(root, tagname):
* Find all descendants of the specified root element that have the
* specified tagname. If any of these elements have an attribute named
* shadow, then call Shadows.add(), for the element and the value of its
* shadow attribute. If tagname is not specified, all elements are checked.
* If root is not specified, the document object is used. This function is
* intended to be called once, when a document is first loaded.
*
* Shadow Syntax
*
* Shadows are specified by a string of the form [x y color]+. That is, one
* or more triplets specifying an x offset a y offset and a color. Each of
* these values must be in legal CSS format. If more than one shadow is
* specified, then the first shadow specified is on the bottom, overlapped
* by subsequent shadows. For example: "4px 4px #ccc 2px 2px #aaa"
*/varShadows = {};
// Add shadows to a single specified element
Shadows.add = function(element, shadows) {
if (typeof element == "string")
element = document.getElementById(element);
// Break the shadows string up at whitespace, first stripping off
// any leading and trailing spaces.
shadows = shadows.replace(/^\s+/, "").replace(/\s+$/, "");
varargs = shadows.split(/\s+/);
// Find the text node that we are going to shadow.
// This module would be more robust if we shadowed all children.
// For simplicity, though, we're only going to do one.
vartextnode = element.firstChild;
// Give the container element relative positioning, so that
// shadows can be positioned relative to it.
// We'll learn about scripting the style property in this way later.
element.style.position = "relative";
// Create the shadows
varnumshadows = args.length/3; // how many shadows?
for(vari = 0; i < numshadows; i++) { // for each one
varshadowX = args[i*3]; // get the X offset
varshadowY = args[i*3 + 1]; // the Y offset
varshadowColor = args[i*3 + 2]; // and the color arguments
// Create a new <span> to hold the shadow
varshadow = document.createElement("span");
// Use its style attribute to specify offset and color
shadow.setAttribute("style", "position:absolute; " +
"left:" + shadowX + "; " +
"top:" + shadowY + "; " +
"color:" + shadowColor + ";");
// Add a copy of the text node to this shadow span
shadow.appendChild(textnode.cloneNode(false));
// And add the span to the container
element.appendChild(shadow);
}
// Now we put the text on top of the shadow. First, create a <span>
vartext = document.createElement("span");
text.setAttribute("style", "position: relative"); // position it
text.appendChild(textnode); // Move the original text node to this span
element.appendChild(text); // And add this span to the container
};
// Scan the document tree at and beneath the specified root element for
// elements with the specified tagname. If any have a shadow attribute
// pass it to the Shadows.add() method above to create the shadow.
// If root is omitted, use the document object. If tagname is omitted,
// search all tags.
Shadows.addAll = function(root, tagname) {
if (!root) root = document; // Use whole document if no root
if (!tagname) tagname = '*'; // Use any tag if no tagname specified
varelements = root.getElementsByTagName(tagname); // Find all tags
for(vari = 0; i < elements.length; i++) { // For each tag
varshadow = elements[i].getAttribute("shadow"); // If it has a shadow
if (shadow) Shadows.add(elements[i], shadow); // create the shadow
}
};
/**
* AnimateCSS.js:
* This file defines a function named animateCSS(), which serves as a framework
* for creating CSS-based animations. The arguments to this function are:
*
* element: The HTML element to be animated.
* numFrames: The total number of frames in the animation.
* timePerFrame: The number of milliseconds to display each frame.
* animation: An object that defines the animation; described below.
* whendone: An optional function to call when the animation finishes.
* If specified, this function is passed element as its argument.
*
* The animateCSS() function simply defines an animation framework. It is
* the properties of the animation object that specify the animation to be
* done. Each property should have the same name as a CSS style property. The
* value of each property must be a function that returns values for that
* style property. Each function is passed the frame number and the total
* amount of elapsed time, and it can use these to compute the style value it
* should return for that frame. For example, to animate an image so that it
* slides in from the upper left, you might invoke animateCSS as follows:
*
* animateCSS(image, 25, 50, // Animate image for 25 frames of 50ms each
* { // Set top and left attributes for each frame as follows:
* top: function(frame,time) { return frame*8 + "px"; },
* left: function(frame,time) { return frame*8 + "px"; }
* });
*
**/functionanimateCSS(element, numFrames, timePerFrame, animation, whendone) {
varframe = 0; // Store current frame number
vartime = 0; // Store total elapsed time
// Arrange to call displayNextFrame() every timePerFrame milliseconds.
// This will display each of the frames of the animation.
varintervalId = setInterval(displayNextFrame, timePerFrame);
// The call to animateCSS() returns now, but the previous line ensures that
// the following nested function will be invoked once for each frame
// of the animation.
functiondisplayNextFrame() {
if (frame >= numFrames) { // First, see if we're done
clearInterval(intervalId); // If so, stop calling ourselves
if (whendone) whendone(element); // Invoke whendone function
return; // And we're finished
}
// Now loop through all properties defined in the animation object
for(var cssprop in animation) {
// For each property, call its animation function, passing the
// frame number and the elapsed time. Use the return value of the
// function as the new value of the corresponding style property
// of the specified element. Use try/catch to ignore any
// exceptions caused by bad return values.
try {
element.style[cssprop] = animation[cssprop](frame, time);
} catch(e) {}
}
frame++; // Increment the frame number
time += timePerFrame; // Increment the elapsed time
}
}
Fires when the pointing device button is clicked over an element. A click is defined as a mousedown and mouseup over the same screen location. The sequence of these events is:
mousedown
mouseup
click
Yes
Yes
dblclick
ondblclick
Fires when the pointing device button is double clicked over an element.
Yes
Yes
mousedown
onmousedown
Fires when the pointing device button is pressed over an element.
Yes
Yes
mouseup
onmouseup
Fires when the pointing device button is released over an element.
Yes
Yes
mouseover
onmouseover
Fires when the pointing device button is moved onto an element.
Yes
Yes
mousemove
onmousemove
Fires when the pointing device button is moved while it is over an element.
Yes
No
mouseout
onmouseout
Fires when the pointing device button is moved away from an element.
Yes
Yes
Keyboard
keypress
onkeypress
Fires when a key on the keyboard is "clicked". A keypress is defined as a keydown and keyup on the same key. The sequence of these events is:
keydown
keyup
keypress
Yes
Yes
keydown
onkeydown
Fires when a key on the keyboard is pressed.
Yes
Yes
keyup
onkeyup
Fires when a key on the keyboard is released.
Yes
Yes
HTML frame/object
load
onload
Fires when finishes loading all content within a document, including window, frame, object and image.
No
No
unload
onunload
Fires when removes all content from a window or frame.
No
No
abort
onabort
Fires when an object/image loading is stopped before completely loaded.
Yes
No
error
onerror
Fires when an object/image/frame cannot be loaded properly.
Yes
No
resize
onresize
Fires when a document view is resized.
Yes
No
scroll
onscroll
Fires when a document view is scrolled.
Yes
No
HTML form
select
onselect
Fires when a user selects some text in a text field, including input and textarea.
Yes
No
change
onchange
Fires when a control loses the input focus and its value has been modified since gaining focus, including input, select and textarea.
Yes
No
submit
onsubmit
Fires when a form is submitted.
Yes
Yes
reset
onreset
Fires when a form is reset.
Yes
No
focus
onfocus
Fires when an element receives focus either via the pointing device or by tabbing navigation, including label, input, select, textarea, and button.
No
No
blur
onblur
Fires when an element loses focus either via the pointing device or by tabbing navigation, including label, input, select, textarea, and button.
No
No
User interface
DOMFocusIn
ondomfocusin
Similar to HTML focus event, but can be applied to any focusable element.
Yes
No
DOMFocusOut
ondomfocusout
Similar to HTML blur event, but can be applied to any focusable element.
Yes
No
DOMActivate
ondomactivate
Similar to XUL command event. Fires when an element is activated, for instance, through a mouse click or a keypress.
Yes
Yes
Mutation
DOMSubtreeModified
onsubtreemodified
Fire when the subtree is modified.
Yes
No
DOMNodeInserted
onnodeinserted
Fires when a node has been added as a child of another node.
Yes
No
NodeInsertedIntoDocument
onnodeinsertedintodocument
Fires when a node is being inserted into a document.
The load event occurs when the DOM implementation finishes
loading all content within a document, all frames within a
FRAMESET, or an OBJECT element.
Bubbles: No
Cancelable: No
Context Info: None
unload
The unload event occurs when the DOM implementation removes a
document from a window or frame. This event is valid for BODY and
FRAMESET elements.
Bubbles: No
Cancelable: No
Context Info: None
abort
The abort event occurs when page loading is stopped before an
image has been allowed to completely load. This event applies to
OBJECT elements.
Bubbles: Yes
Cancelable: No
Context Info: None
error
The error event occurs when an image does not load properly or
when an error occurs during script execution. This event is valid
for OBJECT elements, BODY elements, and FRAMESET element.
Bubbles: Yes
Cancelable: No
Context Info: None
select
The select event occurs when a user selects some text in a text
field. This event is valid for INPUT and TEXTAREA elements.
Bubbles: Yes
Cancelable: No
Context Info: None
change
The change event occurs when a control loses the input focus
and its value has been modified since gaining focus. This event is
valid for INPUT, SELECT, and TEXTAREA. element.
Bubbles: Yes
Cancelable: No
Context Info: None
submit
The submit event occurs when a form is submitted. This event
only applies to the FORM element.
Bubbles: Yes
Cancelable: Yes
Context Info: None
reset
The reset event occurs when a form is reset. This event only
applies to the FORM element.
Bubbles: Yes
Cancelable: No
Context Info: None
focus
The focus event occurs when an element receives focus either
via a pointing device or by tabbing navigation. This event is valid
for the following elements: LABEL, INPUT, SELECT, TEXTAREA, and
BUTTON.
Bubbles: No
Cancelable: No
Context Info: None
blur
The blur event occurs when an element loses focus either via
the pointing device or by tabbing navigation. This event is valid
for the following elements: LABEL, INPUT, SELECT, TEXTAREA, and
BUTTON.
Bubbles: No
Cancelable: No
Context Info: None
resize
The resize event occurs when a document view is resized.
Bubbles: Yes
Cancelable: No
Context Info: None
scroll
The scroll event occurs when a document view is scrolled.
Bubbles: Yes
Cancelable: No
Context Info: None
6.1.2 Event Object
The Event object (handler gets passed) has properties:
type: event type.
target: node on which event
occurred.
currentTarget: node at which event is
currently being processed.
eventPhase: number that specifies current
phase of event propagation.
timeStamp: a Date object of when the
event occurred.
bubbles: does this event bubble up?
cancelable: does it have a default action that can be canceled with the preventDefault() method?
UIEvent inherits from Event and has (in addition):
view: window object within which the
event occurred.
detail: number with more info. For clicks
its 1 for single click, 2 for double click, 3 for
triple.
MouseEvent inherits from both.
button: number of button pressed
(0,1,2)
alkKey, ctrlKey, metaKey, shiftKey:
booleans. Was it held down?
clientX, clientY: coordinates of mouse
relative to browser window.
screenX, screenY: coordinates of mouse
relative to screen.
relatedTarget: for mousemovement events it is the node the mouse left.
/**
* Drag.js: drag absolutely positioned HTML elements.
*
* This module defines a single drag() function that is designed to be called
* from an onmousedown event handler. Subsequent mousemove events will
* move the specified element. A mouseup event will terminate the drag.
* If the element is dragged off the screen, the window does not scroll.
* This implementation works with both the DOM Level 2 event model and the
* IE event model.
*
* Arguments:
*
* elementToDrag: the element that received the mousedown event or
* some containing element. It must be absolutely positioned. Its
* style.left and style.top values will be changed based on the user's
* drag.
*
* event: the Event object for the mousedown event.
**/functiondrag(elementToDrag, event) {
// The mouse position (in window coordinates)
// at which the drag begins
varstartX = event.clientX, startY = event.clientY;
// The original position (in document coordinates) of the
// element that is going to be dragged. Since elementToDrag is
// absolutely positioned, we assume that its offsetParent is the
// document body.
varorigX = elementToDrag.offsetLeft, origY = elementToDrag.offsetTop;
// Even though the coordinates are computed in different
// coordinate systems, we can still compute the difference between them
// and use it in the moveHandler() function. This works because
// the scrollbar position never changes during the drag.
vardeltaX = startX - origX, deltaY = startY - origY;
// Register the event handlers that will respond to the mousemove events
// and the mouseup event that follow this mousedown event.
if (document.addEventListener) { // DOM Level 2 event model
// Register capturing event handlers
document.addEventListener("mousemove", moveHandler, true);
document.addEventListener("mouseup", upHandler, true);
}
elseif (document.attachEvent) { // IE 5+ Event Model
// In the IE event model, we capture events by calling
// setCapture() on the element to capture them.
elementToDrag.setCapture();
elementToDrag.attachEvent("onmousemove", moveHandler);
elementToDrag.attachEvent("onmouseup", upHandler);
// Treat loss of mouse capture as a mouseup event
elementToDrag.attachEvent("onlosecapture", upHandler);
}
else { // IE 4 Event Model
// In IE 4 we can't use attachEvent() or setCapture(), so we set
// event handlers directly on the document object and hope that the
// mouse events we need will bubble up.
varoldmovehandler = document.onmousemove; // used by upHandler()
varolduphandler = document.onmouseup;
document.onmousemove = moveHandler;
document.onmouseup = upHandler;
}
// We've handled this event. Don't let anybody else see it.
if (event.stopPropagation) event.stopPropagation(); // DOM Level 2
else event.cancelBubble = true; // IE
// Now prevent any default action.
if (event.preventDefault) event.preventDefault(); // DOM Level 2
else event.returnValue = false; // IE
/**
* This is the handler that captures mousemove events when an element
* is being dragged. It is responsible for moving the element.
**/functionmoveHandler(e) {
if (!e) e = window.event; // IE Event Model
// Move the element to the current mouse position, adjusted as
// necessary by the offset of the initial mouse-click.
elementToDrag.style.left = (e.clientX - deltaX) + "px";
elementToDrag.style.top = (e.clientY - deltaY) + "px";
// And don't let anyone else see this event.
if (e.stopPropagation) e.stopPropagation(); // DOM Level 2
else e.cancelBubble = true; // IE
}
/**
* This is the handler that captures the final mouseup event that
* occurs at the end of a drag.
**/functionupHandler(e) {
if (!e) e = window.event; // IE Event Model
// Unregister the capturing event handlers.
if (document.removeEventListener) { // DOM event model
document.removeEventListener("mouseup", upHandler, true);
document.removeEventListener("mousemove", moveHandler, true);
}
elseif (document.detachEvent) { // IE 5+ Event Model
elementToDrag.detachEvent("onlosecapture", upHandler);
elementToDrag.detachEvent("onmouseup", upHandler);
elementToDrag.detachEvent("onmousemove", moveHandler);
elementToDrag.releaseCapture();
}
else { // IE 4 Event Model
// Restore the original handlers, if any
document.onmouseup = olduphandler;
document.onmousemove = oldmovehandler;
}
// And don't let the event propagate any further.
if (e.stopPropagation) e.stopPropagation(); // DOM Level 2
else e.cancelBubble = true; // IE
}
}
Drag me
This is the content of the box which can be dragged by grabbing its title.
// This generic function appends details of an event to the big Textarea
// element in the form above. It is called from various event handlers.
functionreport(element, event) {
if ((element.type == "select-one") || (element.type == "select-multiple")){
value = "";
for(vari = 0; i < element.options.length; i++)
if (element.options[i].selected)
value += element.options[i].value + "";
}
elseif (element.type == "textarea") value = "...";
else value = element.value;
varmsg = event + ": " + element.name + ' (' + value + ')\n';
vart = element.form.textarea;
t.value = t.value + msg;
}
// This function adds a bunch of event handlers to every element in a form.
// It doesn't bother checking to see if the element supports the event handler,
// it just adds them all. Note that the event handlers call report().
// We're defining event handlers by assigning functions to the
// properties of JavaScript objects rather than by assigning strings to
// the attributes of HTML elements.
functionaddhandlers(f) {
// Loop through all the elements in the form
for(vari = 0; i < f.elements.length; i++) {
vare = f.elements[i];
e.onclick = function() { report(this, 'Click'); }
e.onchange = function() { report(this, 'Change'); }
e.onfocus = function() { report(this, 'Focus'); }
e.onblur = function() { report(this, 'Blur'); }
e.onselect = function() { report(this, 'Select'); }
}
// Define some special-case event handlers for the three buttons:
f.clearbutton.onclick = function() {
this.form.textarea.value=''; report(this,'Click');
}
f.submitbutton.onclick = function () {
report(this, 'Click'); returnfalse;
}
f.resetbutton.onclick = function() {
this.form.reset(); report(this, 'Click'); returnfalse;
}
}
// Finally, activate our form by adding all possible event handlers!
addhandlers(document.getElementById("everything"));
8 Cookies
Access cookies with document.cookie with a string of the form “name = value; name = value;”
Cookie cannot have semicolons, commas, or whitespace, so
you'll want to
encodeURIComponent(mycookiestring).
Set lifetime with “max-age=seconds”
9 Getting Data From Server
img, script, and
iframe tags have a src attribute
which get info from server.
The iframe fetches HTML so its contents can
be inspected by your JavaScript.
But, better to use XMLHttpRequest.
9.1 XMLHttpRequest
Lets you asynchronously fetch data from server. Need
not be XML data.
You can do POST, GET, and HEAD requests.
9.1.1 Creating an XMHHttpRequest Object
Of course, it is different in IE vs everywhere else, thus:
// This is a list of XMLHttpRequest creation factory functions to try
HTTP._factories = [
function() { returnnew XMLHttpRequest(); },
function() { returnnew ActiveXObject("Msxml2.XMLHTTP"); },
function() { returnnew ActiveXObject("Microsoft.XMLHTTP"); }
];
// When we find a factory that works, store it here
HTTP._factory = null;
// Create and return a new XMLHttpRequest object.
//
// The first time we're called, try the list of factory functions until
// we find one that returns a nonnull value and does not throw an
// exception. Once we find a working factory, remember it for later use.
//
HTTP.newRequest = function() {
if (HTTP._factory != null) return HTTP._factory();
for(vari = 0; i < HTTP._factories.length; i++) {
try {
varfactory = HTTP._factories[i];
varrequest = factory();
if (request != null) {
HTTP._factory = factory;
return request;
}
}
catch(e) {
continue;
}
}
// If we get here, none of the factory candidates succeeded,
// so throw an exception now and for all future calls.
HTTP._factory = function() {
thrownew Error("XMLHttpRequest not supported");
}
HTTP._factory(); // Throw an error
}
9.1.2 Submitting a Request
request.open("GET",url,false), name and
password as optional fourth and fifth arguments.
Does not send request, just stores arguments. You can also set:
There is no stop button for
XMLHttpRequests. Thus, you should use asynchronous.
9.1.4 Asynchronous Response
Pass true as third argument to
open().
Set event handler on onreadystatechange property.
varrequest = HTTP.newRequest();
//Register event handler
request.onreadystatechange = function() {
if (request.readyState == 4) { //if request is finished
if (request.status == 200) // if it was successful
alert(request.responseText);
}
}
request.open("GET", url);
request.send(null);
During long downloads Firefox calls it with readyState == 3 many times, but IE does it only once.
9.1.5 Security
XMLHttpRequest can only make HTTP calls, and
only to the server from which the document it is in was
downloaded.
You cannot test using file://.
9.2 Examples
/**
* Use XMLHttpRequest to fetch the contents of the specified URL using
* an HTTP GET request. When the response arrives, pass it (as plain
* text) to the specified callback function.
*
* This function does not block and has no return value.
*/
HTTP.getText = function(url, callback) {
varrequest = HTTP.newRequest();
request.onreadystatechange = function() {
if (request.readyState == 4 && request.status == 200)
callback(request.responseText);
}
request.open("GET", url);
request.send(null);
};
HTTP.getXML = function(url, callback) {
varrequest = HTTP.newRequest();
request.onreadystatechange = function() {
if (request.readyState == 4 && request.status == 200)
callback(request.responseXML);
}
request.open("GET", url);
request.send(null);
};
/**
* Send an HTTP POST request to the specified URL, using the names and values
* of the properties of the values object as the body of the request.
* Parse the server's response according to its content type and pass
* the resulting value to the callback function. If an HTTP error occurs,
* call the specified errorHandler function, or pass null to the callback
* if no error handler is specified.
**/
HTTP.post = function(url, values, callback, errorHandler) {
varrequest = HTTP.newRequest();
request.onreadystatechange = function() {
if (request.readyState == 4) {
if (request.status == 200) {
callback(HTTP._getResponse(request));
}
else {
if (errorHandler) errorHandler(request.status,
request.statusText);
else callback(null);
}
}
}
request.open("POST", url);
// This header tells the server how to interpret the body of the request
request.setRequestHeader("Content-Type",
"application/x-www-form-urlencoded");
// Encode the properties of the values object and send them as
// the body of the request.
request.send(HTTP.encodeFormData(values));
};
/**
* Encode the property name/value pairs of an object as if they were from
* an HTML form, using application/x-www-form-urlencoded format
*/
HTTP.encodeFormData = function(data) {
varpairs = [];
varregexp = /%20/g; // A regular expression to match an encoded space
for(var name in data) {
varvalue = data[name].toString();
// Create a name/value pair, but encode name and value first
// The global function encodeURIComponent does almost what we want,
// but it encodes spaces as %20 instead of as "+". We have to
// fix that with String.replace()
varpair = encodeURIComponent(name).replace(regexp,"+") + '=' +
encodeURIComponent(value).replace(regexp,"+");
pairs.push(pair);
}
// Concatenate all the name/value pairs, separating them with &
return pairs.join('&');
};
9.2.2 Handling a JSON Response
HTTP._getResponse = function(request) {
// Check the content type returned by the server
switch(request.getResponseHeader("Content-Type")) {
case "text/xml":
// If it is an XML document, use the parsed Document object
return request.responseXML;
case "text/json":
case "application/json":
case "text/javascript":
case "application/javascript":
case "application/x-javascript":
// If the response is JavaScript code, or a JSON-encoded value,
// call eval() on the text to "parse" it to a JavaScript value.
// Note: only do this if the JavaScript code is from a trusted server!
return eval(request.responseText);
default:
// Otherwise, treat the response as plain text and return as a string
return request.responseText;
}
};
9.2.3 Timing Out a Request
Set your own timeout with Window.setTimout()
function. Remember to clearTimeout() if you do
get the response, or XMLHttpRequest.abort() if you don't.
/**
* Send an HTTP GET request for the specified URL. If a successful
* response is received, it is converted to an object based on the
* Content-Type header and passed to the specified callback function.
* Additional arguments may be specified as properties of the options object.
*
* If an error response is received (e.g., a 404 Not Found error),
* the status code and message are passed to the options.errorHandler
* function. If no error handler is specified, the callback
* function is called instead with a null argument.
*
* If the options.parameters object is specified, its properties are
* taken as the names and values of request parameters. They are
* converted to a URL-encoded string with HTTP.encodeFormData() and
* are appended to the URL following a '?'.
*
* If an options.progressHandler function is specified, it is
* called each time the readyState property is set to some value less
* than 4. Each call to the progress handler function is passed an
* integer that specifies how many times it has been called.
*
* If an options.timeout value is specified, the XMLHttpRequest
* is aborted if it has not completed before the specified number
* of milliseconds have elapsed. If the timeout elapses and an
* options.timeoutHandler is specified, that function is called with
* the requested URL as its argument.
**/
HTTP.get = function(url, callback, options) {
varrequest = HTTP.newRequest();
varn = 0;
vartimer;
if (options.timeout)
timer = setTimeout(function() {
request.abort();
if (options.timeoutHandler)
options.timeoutHandler(url);
},
options.timeout);
request.onreadystatechange = function() {
if (request.readyState == 4) {
if (timer) clearTimeout(timer);
if (request.status == 200) {
callback(HTTP._getResponse(request));
}
else {
if (options.errorHandler)
options.errorHandler(request.status,
request.statusText);
else callback(null);
}
}
elseif (options.progressHandler) {
options.progressHandler(++n);
}
}
vartarget = url;
if (options.parameters)
target += "?" + HTTP.encodeFormData(options.parameters)
request.open("GET", target);
request.send(null);
};