Making IE recognize HTML5 elements

IE6, IE7 and IE8 don’t recognize the HTML elements. This causes a major problem when you’re using the HTML5 elements, such as ‘aside’, as part of (or your complete) selector in your CSS. Add this snippet either in your HTML or as a condionally included file, and IE will be able to handle your HTML5 elements as selectors in your CSS, and as members of your DOM in javascript. (thanks to John Resig for the inspiration)

<!--[if IE]>
<script type="text/javascript">
(function(){
var html5elmeents = "address|article|aside|audio|canvas|command|datalist|details|dialog|figure|figcaption|footer|header|hgroup|keygen|mark|meter|menu|nav|progress|ruby|section|time|video".split('|');
for(var i = 0; i < html5elmeents.length; i++){
document.createElement(html5elmeents[i]);
}
}
)();
</script>
<![endif]-->

Printing HTML5 in Internet Explorer: where HTML5 is not supported

The code snipped above does wonders for enabling the various Internet Explorer’s to understand HTML5 elements as element selectors for scressn media, it does nothing to enable print CSS. The above javascript doesn’t cure the ‘print’ issue. Jonathan Neal has come up with a javascript solution to the IE HTML5 print issue.

IE Print Protector is a javascript file that allows you to print HTML5 pages in Internet Explorer, helping IE render HTML5 elements correctly, both on screen and in print.

iPhone: HTML, CSS & JS Support


See Estelle at the 2nd annual CSS Summit
Wouldn’t it be cool to be able to use CSS3 and HTML5 unfettered by the lack of support in IE? Mobile developers for smart phones get to do just that! When developing for mobile devices using webkit browsers we can use CSS animations, transforms, multiple background images, rounded corners, text and box shadows, CSS columns, and HTML5 form elements.

In my CSS Summit session we’ll use some CSS3 features learned in earlier sessions to create a native looking iPhone web app. We’ll also cover some CSS UI and HTML5 form elements that will help you get up to speed on developing for mobile webkit. You don’t have to wait any longer to use CSS3! Join Us!



Safari and Safari for the iPhone support all HTML elements, including deprecated elements and even some proprietary elements that were never part of any W3C specifications. In addtion, Safari is supporting some HTML5 elements, even though the HTML5 specifications have not been finalized. I’ve also added the attributes that each element supports. I didn’t include id, class, style, dir & title, since all elements basically support those, but I did include element specific attributes as well as some webkit only attributes.

iPhone Support for CSS3 Selectors

All CSS Selectors are supported by Safari on the iPhone. See CSS browser support for a chartcomparison of all the selectors. Selectos include:

  • *
  • E
  • .class
  • #id
  • E F
  • E > F
  • E + F
  • E[attribute]
  • E[attribute=value]
  • E[attribute~=value]
  • E[attribute|=value]
  • :first-child
  • :link
  • :visited
  • :lang()
  • :before
  • ::before
  • :after
  • ::after
  • :first-letter
  • ::first-letter
  • :first-line
  • ::first-line
  • E[attribute^=value]
  • E[attribute$=value]
  • E[attribute*=value]
  • E ~ F
  • :root
  • :last-child
  • :only-child
  • :nth-child()
  • :nth-last-child()
  • :first-of-type
  • :last-of-type
  • :only-of-type
  • :nth-of-type()
  • :nth-last-of-type()
  • :empty
  • :not()
  • :target
  • :enabled
  • :disabled
  • :checked
  • see them all

iPhone Support for CSS3 properties

Almost all CSS2.1 properties and values are supported by Safari on the iPhone, except for some keyword values for content. Position: absolute is supported, but due to the viewport, does not appear to be supported. See the list of all CSS2.1 properties and values by browser for more details. In addition, the iPhone Safari browser supports some CSS3 type properties and values including:

Some CSS3 including the following, which will be discussed in future blog posts.

  • hsl(), rgba(), hsla() color support
  • native rounded corners (-webkit-border-radius)
  • IE box model (-webkit-box-sizing)
  • Shadows on text (text-shadow was in CSS2.0)
  • Shadows on elements (-webkit-box-shadow)
  • multiple background images
  • opacity /gradient transparency
  • @font-face web fonts
  • CSS Animation
  • Media Queries
  • namespaces

iPhone & Safari Support for HTML elements, including HTML5

includes HTML attributes for the iPhone and Safari

Below is a grid of all of the elements, including deprecated elements (at the way bottom), and HTML5 elements interspersed with HTML4 elements in alphabetical order.

<ELEMENT> Element Name Safari
Version
iPhone Support Attributes (and Notes in italic)
Elements occuring outside the body element
<!DOCTYPE> Document Type Declaration 1.0 1.0
<html> html 1.0 1.0 manifest (Saf. 4, iphone 2.2)
<head> document head 1.0 1.0 profile
<base /> url base for links 1.0 1.0 href, target
<link /> link 1.0 1.0 charset, href, media, rel, rev, target
<meta /> meta 1.0 1.0 content, name, http-equiv, scheme
<style> style 1.0 1.0 media, type
<script> script 1.0 1.0 charset, defer, language, src, type
<title> document title 1.0 1.0
Elements Occuring in the <body> in HTML 4.01 and HTML5
<body> document body 1.0 1.0 bgproperties (value: fixed)
<a> Anchor 1.0 1.0 different event handlers for iPhone than Safari
accesskey, charset, href (required), hreflang, rel, rev, shape (rect/cirlce/poly), target (deprecated, but useful), type
<abbr> Abbreviation 1.0 1.0 title shows on hover in Safari
<acronym> acronym 1.0 1.0 title shows on hover in Safari
<address> address 1.0 1.0 italic
<area> image map area 1.0 1.0 accesskey, alt (required), coords, href (required), hreflang, shape (rect/cirlce/poly), target
<article> HTML5
<aside> HTML5
<audio> audio 3.1 3.0 HTML5: Similar to object, can nest sources and content to cascade until supported found.
Audio support includes AAC, M4A, MP3, Wave, AIFF , Apple Lossless, Quicktime, but not OGG;

autoplay, controls, end, loopend, loopstart, playcount, src, start
<bdo> bi-directional override 1.0 1.0
<blockquote> long quote 1.0 1.0 cite
<br> break return or forced line break 1.0 1.0
<button> push button 1.0 1.0 accesskey, disabled, type, value
<canvas> canvas drawing region 1.3 1.0 HTML5: Stroke and fill colors, rgba/hsla colors, paths, rectangles, shadows, gradients, patterns, translations, rotation and scale
<caption> caption 1.0 1.0
<cite> citation 1.0 1.0
<code> code 1.0 1.0
<col /> column 1.0 1.0 char, charoff, span
<colgroup> column group 1.0 1.0 char, charoff, span
<dd> definition description 1.0 1.0
<del> delete 1.0 1.0 datetime
<dfn> definition 1.0 1.0
<div> generic block element 1.0 1.0 aria-checked, aria-level, aria-pressed, aria-valuemax, aria-valuemin, aria-valuenow, role (Safari 4.0)
<dl> definition list 1.0 1.0
<dt> definition term 1.0 1.0
<em> emphasized text 1.0 1.0
<fieldset> field set 1.0 1.0
<figure> HTML5
<footer> HTML5
<form> form 1.0 1.0 accept, accept-charset, action, enctype. method, target
<frame /> frame 1.0 1.0 frameborder, longdesc, marginheight, marginwidth, noresize, scrolling (yes/no/auto), src
<frameset> frameset 1.0 1.0 cols, rows
<h1-6> headers 1.0 1.0
<header> HTML5
<hgroup> HTML5
<hr /> horizontal rule 1.0 1.0
<iframe> internal frame 1.0 1.0 frameborder, longdesc, marginheight, marginwidth, scrolling (yes/no/auto), src
<img /> image 1.0 1.0 alt (required), composite, ismap, longdesc, src, usemap
<input /> input 1.0 1.0 accept, accesskey, alt, autocapitalize (iphone 1.1, values: on/off), autocomplete, autocorrect (iphone 1.1, values: on/off), autosave (safari), checked, disabled, incremental (safari), ismap, max, maxlength, min, placeholder, results, src, type, usemap, value
<ins> Insert 1.0 1.0 datetime
<kbd> keyboard 1.0 1.0
<keygen> key generation 1.0 1.0 challenge, keytype
<label> label 1.0 1.0 accesskey, for
<legend> caption for fieldset 1.0 1.0 accesskey
<li> list item 1.0 1.0 type, value
<map> image map 1.0 1.0
<mark> HTML5
<meter> HTML5
<object> object 1.0 1.0 archive, classid, codetype, data, declare, loop, type, usemap
<ol> ordered list 1.0 1.0 type
<optgroup> option group 1.0 1.0 disabled, label
<option> option 1.0 1.0 disabled, label, selected, value
<p> paragraph 1.0 1.0
<param> parameter 1.0 1.0 type, value, valuetype
<pre> preformatted text 1.0 1.0
<progress> HTML5
<q> inline quotation 1.0 1.0 cite
<samp> sample computer code 1.0 1.0
<select> option selector 1.0 1.0 disabled, multiple
<source> 3.1 HTML5
media
<span> span (generic non-semantic container) 1.0 1.0 aria-checked, aria-level, aria-pressed, aria-valuemax, aria-valuemin, aria-valuenow, role (Safari 4)
<strong> strong emphasized text 1.0 1.0
<sub> subscript 1.0 1.0
<sup> superscript 1.0 1.0
<table> data table 1.0 1.0 frame (values: above, below, hsides, vsides, rhs, lhs, box, border), rules (values: none, groups, rows, cols, and all), summary
<tbody> table body 1.0 1.0 char, charoff
<td> table data cell 1.0 1.0 abbr, axis, char, charoff, colspan, headers, rowspan, scope
<textarea> text area 1.0 1.0 accesskey, cols, disabled, readonly, rows, wrap
<time> HTML5
<tfoot> table footer 1.0 1.0 char, charoff
<th> table header cell 1.0 1.0 abbr, axis, char, charoff, colspan, headers, rowspan, scope
<thead> table head 1.0 1.0 char, charoff
<tr> table row 1.0 1.0 char, charoff
<ul> unordered list 1.0 1.0
<var> variable 1.0 1.0
<video> video 3.1 3.0 HTML5
autoplay, controls, end, loopend, loopstart, playcount, poster, src, start
Elements you should not be using, that are still valid
<tt> teletype 1.0 1.0
<i> italic
<b> bold
<big> big font
<small> small font
<noframes> no frames 1.0 1.0
<noscript> no script 1.0 1.0
Elements that are deprecated or were never in a W3C spec, but you may still see on older websites
<applet> applet 1.0
<center> center 1.0 1.0
<dir> direction 1.0 1.0
<embed> embed 1.0 1.0 use object instead
hidden, loop, pluginpage, pluginspage, pluginurl
<font> font 1.0 1.0
<layer> layer 1.0 1.0
<listing> listing 3.0 1.0 use <pre> instead. from HTML 3.2
<marquee> ,arquee 1.0 1.0 behavior, direction, loop, scrollamount, scrolldelay, truespeed
<menu> menu 1.0 1.0
<nobr> no break 1.0 1.0
<noembed> no embed 1.0 1.0
<nolayer> no layer 1.0 1.0
<plaintext> plaintext 1.0 1.0
<strike> strikethrough 1.0 1.0 use <del>
<u> underline
<wbr> with breaks 1.0 1.0
<xmp> sequence of literal characters 1.o 1.0


Safari and iPhone Event Handlers:

Event Safari iPhone Explanation
onabort 1.0 1.0 When an image element is aborted during load. (for <img /> elements)
onbeforecopy 1.3 before the element is copied.
onbeforecut 1.3 before the element is cut.
onbeforepaste 1.3 before the element has something pasted into it.
onbeforeunload 1.3 before the element is unloaded from the page.
onblur 1.0 1.0 when the element loses focus.
onchange 1.0 1.0 when the element changes its value.
onclick 1.0 1.0 when the element is clicked.
oncontextmenu 1.1 when the element is right-clicked or when the mouse button is held down long enough to generate a contextual menu.
oncopy 1.3 when the element is copied.
oncut 1.3 when the element is cut.
ondblclick 1.0 when the element is double-clicked.
ondrag 1.3 when the element is dragged.
ondragend 1.3 when the element is done being dragged.
ondragenter 1.3 when a drag has entered the element.
ondragleave 1.3 when a drag has left the element.
ondragover 1.3 when a drag is over the element.
ondragstart 1.3 when the element has started to be dragged.
ondrop 1.3 when the element is dropped.
onerror 1.0 1.0 when the element has an error in loading.
onfocus 1.0 1.0 when the element gets focus.
ongesturechange 2.0 When fingers are moved during a gesture.

(proprietary)

ongestureend 2.0 When the gesture ends (when there are 1 or 0 fingers touching the surface).

(proprietary)

ongesturestart 2.0 When two or more fingers touch the surface.

(proprietary)

oninput 1.3 1.0 when text is entered into the element.
onkeydown 1.0 1.0 when a key is pressed over the element.
onkeypress 1.0 1.0 when a key is pressed and released over the element.
onkeyup 1.0 1.0 when a key is released over the element.
onload 1.0 1.0 when the element finishes loading.
onmousedown 1.0 1.0 when the mouse button is pressed over the element.
onmousemove 1.0 1.0 when a key is moved within the element.
onmouseout 1.0 1.0 when the mouse leaves the element.
onmouseover 1.0 1.0 when the mouse is over the element.
onmouseup 1.0 1.0 when the mouse button is released over the element.
onmousewheel 1.0 1.0 when the mouse wheel button is rotated.
onorientationchange 1.1 When the orientation of the device changes.
onpaste 1.3 when the element is pasted.
onreset 1.0 1.0 when the form element is reset.
onresize 1.0 1.0 when the element is resized.
onscroll 1.2 1.0 when the element is scrolled (a text box would use this, for example).
onsearch 1.3 when a search is performed.

(proprietary)

onselect 1.0 1.0 when text within the element is selected.
onselectstart 1.3 when the element begins to be selected. You can use this to prevent selections.
onsubmit 1.0 1.0 when the form element is submitted.
ontouchcancel 2.0 When the system cancels tracking for the touch.

(proprietary)

ontouchend 2.0 When a given event lifts from the surface.

(proprietary)

ontouchmove 2.0 When a finger for a given event moves on the surface.

(proprietary)

ontouchstart 2.0 When a finger for a given event touches the surface.

(proprietary)

onunload 2.1 when the element is unloaded from the page.

Other iPhone posts in my blog

16 Common JavaScript Gotchas

We all know that JavaScript can trip you up. Here are a 16 common traps that can trip you up when coding javascript. You likely know most of the code on the page, but if you keep these 16 gotchas in your mind, coding and debugging will be less of a headache:

  1. Case sensitivity: Variable names, properties and methods are all case sensitive
  2. Mismatching quotes, parenthesis or curly braces will throw an error
  3. Conditional Statments:3 common gotchas
  4. Line breaks: Always end statements in semi-colons to avoid common line break issues
  5. Punctuation:Trailing commas in object declarations will trip you up
  6. HTML id conflicts
  7. Variable Scope: global versus local scope
  8. string replace function isn’t global
  9. parseInt should include two arguments
  10. ‘this’ and binding issues
  11. Function overloading: Overwriting functions, as overloading doesn’t exist
  12. Setting default values for parameters in case you omit them
  13. For each loops are for objects, not arrays
  14. switch statements are a little tricky
  15. Always check for Undefined before checking for null
  16. Function location may matter
Case Sensitivity
Variables and function names are case sensitive. Like mismatched quotes, you already know this. But, since the error may be silent, here is the reminder. Pick a naming convention for yourself, and stick with it. And, remember that native javascript function and CSS properties in javascript are camelCase.

getElementById('myId') != getElementByID('myId'); // it should be "Id" not "ID"
getElementById('myId') != getElementById('myID'); // "Id" again does not equal"ID"
document.getElementById('myId').style.Color; // returns "undefined"
Mismatching quotes, parenthesis and curly brace
The best way to avoid falling into the trap of mismatched quotes, parentheses and curly brackets is to always code your opening and closing element at the same time, then step into the element to add your code. Start with:

var myString = ""; //code the quotes before entering your string value
function myFunction(){
     if(){   //close out every bracket when you open one.

	 }
}

//count all the left parens and right parens and make sure they're equal
alert(parseInt(var1)*(parseInt(var2)+parseInt(var3))); //close every parenthesis when a parenthesis is open

Every time you open an element, close it. Put the arguments for a function into the parenthesis after you’ve added the closing parenthesis. If you have a bunch of parenthesis, count the opening parenthesis and then the closing parenthesis, and make sure those two numbers are equal.

Conditional statements (3 gotchas)
  1. All conditional comments must be within parentheses (duh!)
    if(var1 == var2){}
  2. Don’t get tripped up by accidentally using the assignment operator: assigning your second argument’s value to your first argument. Since it’s a logic issue, it will always return true and won’t throw an error.
    if(var1 = var2){} // returns true. Assigns var2 to var1
  3. Javascript is loosely typed, except in switch statements. JavaScript is NOT loosely typed when it comes to case comparisons.
    var myVar = 5;
    if(myVar == '5'){ // returns true since Javascript is loosely typed
      alert("hi");  //this alert will show since JS doesn't usually care about data type.
    }
    switch(myVar){
      case '5':
      alert("hi"); // this alert will not show since the data types don't match
    }
Line Breaks
  • Beware of hard line breaks in JavaScript. Line breaks are interpreted as line-ending semicolons. Even in a string,if you include a hard line break in between quotes you’ll get a parse error (unterminated string).
        var bad  = '<ul id="myId">
                       <li>some text</li>
                       <li>more text</li>
                    </ul>'; // unterminated string error
    
        var good = '<ul id="myId">' +
                       '<li>some text</li>' +
                       '<li>more text</li>' +
                   '</ul>'; //correct
  • The line break being interpreted as a semi-colon rule, discussed above, does not hold true in the case of control structures: line breaks after the closing parenthesis of a conditional statement is NOT given a semi-colon.

Always use semi-colons and parenthesis so you don’t get tripped up by breaking lines, so your code is easier to read, and, less thought of but a source of quirks for those who don’t use semicolons: so when you move code around and end up with two statements on one line, you don’t have to worry that your first statement is correctly closed.

Extra commas
The last property in any JavaScript object definition must never end with a comma. Firefox won’t barf on the trailing, unnecessary commas, but IE will.

HTML id conflicts
The JavaScript DOM bindings allow indexing by HTML id. Functions and properties share the same namespace in JavaScript. So, when an id in your HTML has the same name as one of your functions or properties, you can get logic errors that are hard to track down. While this is more of a CSS best practice issue, it’s important to remember when you can’t solve your javascript issue.

var listitems = document.getElementsByTagName('li');

var liCount = listitems.length; // if you have <li id="length">, returns that <li> instead of a count.

If you’re marking up (X)HTML, never use a javascript method or property name as the value for an ID. And, when you’re coding the javascript, avoid giving variables names that are ID values in the (X)HTML.

variable scope
Many problems in javascript come from variable scope: either thinking that a local variable is global, or overwriting a global variable unwittingly with what should be a local variable in a function. To avoid issues, it’s best to basically not have any global variables. But, if you have a bunch, you should know the “gotchas”.

Variables that are not declared with the var keyword are global. Remember to declare variables with the var keyterm to keep variables from having global scope. In this example, a variable that is declared within a function has global scope because the var ke

anonymousFuntion1 = function(){
	globalvar = 'global scope'; // globally declared because "var" is missing.
	return localvar;
}();

alert(globalvar); // alerts 'global scope' because variable within the function is declared globally

anonymousFuntion2 = function(){
	var localvar = 'local scope'; //locally declared with "var"
	return localvar;
}();

alert(localvar); // error "localvar is not defined". there is no globally defined localvar

Variable names that are introduced as parameter names are local to the function. There is no conflict if your parameter name is also the name of a global variable as the parameter variable has local scope. If you want to change the global variable from within a function that has a parameter duplicating the global variable’s name, remember that global variables are properties of the window object.

var myscope = "global";

function showScope(myscope){
  return myscope; // local scope even though there is a global var with same name
}
alert(showScope('local'));

function globalScope(myscope){
  myscope = window.myscope; // global scope
  return myscope;
}
alert(globalScope('local'));

You should even declare variables within loops

for(var i = 0; i < myarray.length; i++){}
string replace
A common mistake is assuming the behavior of the string replace method will impact all possible matches. Infact, the javascript string replace method only changes the first occurrence. To replace all occurrences, you need to set the global modifier.

  var myString = "this is my string";
  myString = myString.replace(/ /,"%20"); // "this%20is my string"
  myString = myString.replace(/ /g,"%20"); // "this%20is%20my%20string"
parseInt
The most common error with parding integers in javascript is the assumption that parseInt returns the integer to base 10. Don’t forget the second argument, the radix or base, which can be anything from 2 to 36. To ensure you don’t screw up, always include the second parameter.

parseInt('09/10/08'); //0parseInt('09/10/08',10); //9, which is most likely what you want from a date.
‘this’
Another common mistake is forgetting to use ‘this‘. Functions defined on a JavaScript object accessing properties on that JavaScript object and failing to use the ‘this’ reference identifier. For example, the following is incorrect:

function myFunction() {
  var myObject = {
     objProperty: "some text",
     objMethod: function() {
		alert(objProperty);
		}
     };
  myObject.objMethod();
} 

function myFunction() {
  var myObject = {
     objProperty: "some text",
     objMethod: function() {
		alert(this.objProperty);
		}
     };
  myObject.objMethod();
}

There’s an A List Apart article that puts this binding issue into plain English

Overwriting functions / overloading functions
When you declare a function more than once, the last declaration of that function will overwrite all previous version of that function throwing no errors or warnings. This is different from other programming languages, like java, where you can have multiple functions with the same name as long as they take different arguments: called function overloading. There is no overloading in javascript. This makes it vitally important to not use the names of core javascript functions in your code. Also, beware of including multiple javascript files, as an included script may overwrite a function in another script. Use anonymous functions and namespaces.

(function(){
	// creation of my namespace
    // if namespace doesn't exist, create it.	if(!window.MYNAMESPACE) {		window['MYNAMESPACE'] = {}; 		}

    // this function only accessible within the anonymous function
    function myFunction(var1, var2){
		//local function code goes here
    }

    /* attaches the local function to the namespace
       making it accessible outside of the anoymous function with use of namespace */
    window['MYNAMESPACE']['myFunction'] = myFunction; 

 })();// the parenthesis = immediate execution	  // parenthesis encompassing all the code make the function anonymous
Missing Parameters
A common error is forgetting to update all the function calls when you add a parameter to a function. If you need to add a parameter to handle a special case call in your function that you’ve already been calling, set a default value for that parameter in your function, just in case you missed updating one of the calls in one of your scripts.

function addressFunction(address, city, state, country){
      country = country || "US"; // if country is not passed, assume USA
      //rest of code
    }

You can also get the length of the argument array. But we’re focusing on “gotchas” in this post.

For each
The “for” loop in javascript will iterate it over all object attributes, both methods and properties, looping thru all of the property names in an object. The enumeration will include all of the properties—including functions and prototype properties that you might not be interested in—so filter out the values you don’t want using hasOwnProperty method and typeof to exclude functions. Never use for each to iterate thru an array: only use for each when needing to iterated thru object properties and methods.

  • for each (var myVar in myObject) iterates a specified variable over all values of object’s properties.
  • for (var myVar in myObject) iterates a specified variable over all the properties of an object, in arbitrary order. The for...in loop does not iterate over built-in properties. For each distinct property the code is executed
  • for (var 1=0; i < myArray.length; i++) iterates thru all the elements of an array.

To fix the problem, generally you’ll want to opt for for ... in for objects and use the for loop for arrays:

listItems = document.getElementsByTagName('li');

for each (var listitem in listItems){
    // this goes thru all the properties and methods of the object,
    // including native methods and properties, but doesn't go thru the array: throws error!
   }

//since you have an array of objects that you are looping thru, use the for loop
for ( var i = 0; i < listItems.length; i++) {
    // this is what you really wanted
   }
Switch statements
I wrote a whole blog post on switch statement quirks, but the gist is:

  • there is no data type conversion
  • once there is a match, all expressions will be executed until the next break or return statement is executed, and
  • you can include multiple cases for a single block of code
Undefined ≠ null
Null is for an object, undefined is for a property, method or variable. To be null, your object has to be defined. If your object is not defined, and you test to see whether it’s null, since it’s not defined, it can’t test, and will throw an error.

if(myObject !== null  && typeof(myObject) !== 'undefined') {
	//if myObject is undefined, it can't test for null, and will throw an error
}

if(typeof(myObject) !== 'undefined' && myObject !== null) {
	//code handling myObject
}

Harish Mallipeddi has an explanation of undefined versus null

Function location can matter
There are two ways to declare function: When declaring a function in the form of a variable assignment, location does matter:

var myFunction = function(arg1, arg2){
  // do something here
};

A function declared with

function myFunction (arg1, arg2){}

can by used by any code in the file no matter its location (before or after the function declaration). A function declared with the variable assignment syntax can only be used by code that executes after the assignment statement that declares the function.

jQuery Tutorial: DOM Manipulation and sorting

JQuery is a lightweight JavaScript library that helps you quickly develop events, animations, and AJAX interactions.

In this tutorial we go over the following:

Note that the test javascript files associated with each section go with the same XHTML file.

Setting up your environment for this tutorial:


  • Download the JQuery library Generally you will want the minified version, but for today, download the uncompressed version so you can read some of the code if you so choose.
  • Save it locally in a directory (let’s call it “js” for this tutorial)
  • Create a new HTML page (Sample file)
  • Link to the JQuery file – <script type="text/javascript" src="js/jquery-1.2.6.js"></script>
    You may need to change the 1.2.6 part to whatever the current release number is.
  • Create a new javascript file, and call it “myCode.js”
  • Link to your javascript file – <script type="text/javascript" src="js/myCode.js"></script>
  • Add some HTML to your page (this is what we’re going to manipulate).
  • You can also add some CSS.

ready method in anonymous function

The first step is to create an anonymous function withing your myCode.js file to encompass all of your javascript. If you take a look at your JQuery file, you’ll note that the entire file is in an anonymous function:

(function(){
 // code here

})();

All of your the code that you create should be included in it’s own anonymous function. This ensures that the jQuery variables are local: your variable declarations will not break the jQuery library, and the jQuery library will not overwrite your variables, methods and properties.

For our own javascript, we are going to encapsulate all our code in an anonymous function. However, since we are accessing elements of the DOM, we need to ensure that the DOM is loaded. We can’t use the parenthesis at the end as in the code above, which executes the anonymous function immediately, since our DOM isn’t loaded yet. We should only execute our anonymous function once we have the DOM. Without jQuery, and without much Javascript skill, the usual route is to include a document.onLoad event. Instead of using onLoad, which makes us wait until all the images are loaded, we’re going to use jQuery’s ready function — $(document).ready() — which executes when the DOM is ready.

The $(document).ready() function has advantages over other load time event handlers. Everything inside it will load as soon as the DOM is loaded, without having to wait for the page contents to be completely loaded. Ready is fired as soon as the DOM is registered by the browser, which allows for hiding and showing effects and other effects as soon as the user sees the page elements. Unlike the onLoad method, which is limited to only one function, the jQuery ready method allows for multiple functions to be loaded within it.

$(document).ready(function() {
 // code here
 });

Add the code above to your myCode.js file.jQuery

Targeting elements in the DOM with CSS and XPath

jQuery enables selecting elements with the same syntax that you would use to target that element with CSS. For example, we can target the first <h2> in our html file these two ways among others: (test js)

  • $("h2:first")
  • $("#mainContent > h2")

Take a look at the official jQuery Selectors page to get a better understanding of how you can use CSS syntax to target elements.

DOM Manipulation

The following are explanations and examples of the DOM manipulation methods provided by the jQuery core. The jQuery domentation for the DOM manipulation methods can be found at http://docs.jquery.com/Manipulation

jQuery’s version of innerHTML and textNodes

jQuery replaces innerHTML with the html() method to both return and set innerHTML with (and without) HTML elements. To return or set text, similar to retrieving and setting textNodes, use jQuery’s text() method. The main difference between the two involves the returning and rendering of HTML elements. (test js)

  • html()
    returns the HTML content of an element. This is directly equivalent to the innerHTML property commonly used by JavaScripters.
    var myHTMLContent = $("#mainContent").html(); // "<h2>My jQuery te.... (to) ...functionality</p>
  • html(myString)
    Sets the innerHTML for an element to myString.
    $("h2:first").html('This is new <em>header</em> content'); // changes the h2, and adds some emphasis
  • text()
    returns the text content, or text nodes, of an element without any markup as one string
    var myTextContent = $("#mainContent").text(); // returns same as html(), but without tags;
  • text(myString)
    Resets the text node value for an element to myString.
    $("h2:first").text('Ugly <em>header</em>); // escapes '>' and '<' instead of rendering italics

Child & Sibling nodes

append() and prepend() methods: similar to appendChild, except jQuery accepts a string, a DOM element, or a jQuery object as valid arguments. jQuery converts the argument into a text node or element depending on what is passed. (test js)

  1. $("#leftNav ul").append("<li>after the last &lt;li&gt;</li>"); // adds <li> at the end of <ul>
  2. $("#leftNav ul").prepend("<li>before the first &lt;li&gt;</li>"); // adds <li> at the start of <ul>
  3. $("#leftNav ul").append($("#mainContent h2")); // moves headers from the mainContent to the leftNav

  4. $("#leftNav ul").append($("#mainContent h2").html()); //copies text of the first h2, adds it to leftNav

There are two similar methods — appendTo() and prependTo() — which are basically inververted verstions of append() and prepend(). A.append(B) is about equal to B.appendTo(A)

Note: As shown in example 3, if you try to append an element that already exists in the DOM, that element will first be removed from DOM before being reinserted, or appended, in the new location.

before() and after() methods: similar to insertBefore() method (and the non-existant, but found in many javascript libraries, includeing this one, insertAfter()). The after() method inserts a node after a selected one. The before() method inserts a node before a selected one, like the javascript standard method of insertBefore().

  1. $("#leftNav ul").before("<h2>Left Navigation</h2>"); // adds header before the <ul>
  2. $("#leftNav ul").after("<h4>New Header</h4>"); // adds header after the <ul>
  3. $("#leftNav h4").before($("#mainContent h2").html()); //copies text of the first h2, adds it to leftNav before our new <h4>

There are two similar methods — insertBefore() and insertAfter() — which are basically inververted versions of before() and after(). A.before(B) is about equal to B.insertBefore(A)

Parent nodes

wrap(), wrapAll() and wrapInner() methods: wrap selected element or elements in another element. The argument can be an XHTML or DOM element as a string. If the element has child nodes, the element being wrapped will be put in the deepest child node of the first element. (test js)


  1. $("#leftNav ul").wrap("<div class=\"red\"></div>"); // the <ul> gets wrapped in a <div>
  2. $("#mainContent h2").wrap("<blockquote class=\"blue\"></blockquote>"); // the 2 <h2>'s get wrapped in a two separate <blockquote>s
  3. $("#mainContent h2").wrapAll("<blockquote class=\"blue\"></blockquote>"); // the 2 <h2>'s get wrapped in a single <blockquote>, moving the second <h2> up to be the nextSibling to the first <h2>
  4. $("#mainContent h2").wrap('<div class="shell"><div class="blue"></div><ul class="red"><li></li></ul></div>'); // puts the H2s in two "blue" divs, the LIs will be empty.
  5. $("#mainContent h2").wrapAll('<div class="shell"><div class="blue"></div><ul class="red"><li></li></ul></div>'); // puts the H2s in ONE "blue" div, the LI will be empty.
  6. $("#mainContent p").wrapInner("<a href=\"#\"></a>"); // puts an <a> between the <p> and the <p>'s first child.
  7. $("#mainContent").wrapInner("<blockquote class=\"blue\"></blockquote>"); // wraps all the children of #mainContent into one parent <blockquote>

remove() and empty()

remove(), empty() and replace() methods: similar to the native javascript removeChild() method, use remove() to remove element(s) from the DOM. Use the empty() method to keep the element, but remove the element’s children.
Note that remove() can take a parameter, but empty() does not. (test js)

  1. $("#leftNav li:first").remove(); // removes the first LI
  2. $("#leftNav li").remove(); // removes all the LIs from the #leftNav
  3. $("#leftNav li").remove(":contains('Second')"); //remove the LI containing the term.
    Note that the string is case-sensitive
  4. $("#mainContent h2:first").empty(); //removes the text in the first H2, but the h2 is not removed from the DOM
  5. $("#mainContent h2:contains('second')").empty(); //removes the text node child of the H2 containing the letters "second"

replaceWith(), replaceAll() and clone()

replaceWith() and clone() methods: Cloning creates copies of the DOM elements copied, including the new elements in the DOM, but does not append them to the page. To append the clone to the page, use one of the methods above.

  1. $("#leftNav li:first").replaceWith("<li>new first <em>LI</em></li>"); //text changed, LI is emphasized

  2. $("#leftNav li:first").text().replaceWith("new first <em>LI</em>");// grabs text, and replaces it. No <li> needed
  3. var navCopy = $("#leftNav").clone(); //copies it
    $("#mainContent").append(navCopy); //apends it

    The problem with cloning is that IDs are copied too, and ID’s need to be unique!


Effects with JQuery

The above was an overview of all the DOM manipulation functions. If you’re doing a simple site, those are likely all the javascript helpers you need. But, if that was all you could do with JavaScript, then you really wouldn’t need javascript libraries. The power of the libraries is in everything else they do for you. With jQuery you can create drag and drop, autocomplete, sorting, etc., the is unobtrusive and works cross browser in less than 10 lines of javscript. Proof? Here are two examples:

Sorting a table with javascript:

  1. Create a table in plain old XHTML, and populate that table with data. Give your data table the class of sort with: (sampleFile)
    <table class="sort">
  2. Download the jquery libary and the jquery.tablesorter.js file.
  3. Attach the two jQuery files and your own JavaScript file to your XHTML file by including the following in the header of your XHTML file:
    <script type="text/javascript" src="jquery-1.2.6.js"></script>
    <script type="text/javascript" src="jquery.tablesorter.js"></script>
    <script type="text/javascript" src="myTableCode.js"></script>
  4. In your JavaScript file (called myTableCode.js above) include the simple script:
    $(document).ready(function() {
        $("table.sort").tablesorter();
     });
  5. Literally, the previous step is all there is to sorting tables bu column content in However, that just sorts it based on the content of the HTML. So, if you have an <em> or <p> in one table cell and not in another, it may not sort the way you want. To sort based on a portion of your code inside a cell, use the textExtraction utility provided by jQuery:
    $(document).ready(function() {
    
     $("table.sort").tablesorter({
            // define a custom text extraction function
           textExtraction: function(node) {
                // if there is a link, return the content of the link
    		if(node.getElementsByTagName('a')[0]){
    				return node.getElementsByTagName('a')[0].innerHTML;
        			}
            return node.innerHTML;
            }
        });
     });

See my example

Making a list sortable

Similar to the sortable table, you can make a make a list that is sortable by dragging list items around. (example)

  1. Create a list, give it the class of “sortable”.
    <ul class="sortable">
      <li>This is my first list item</li>
      <li>second list item</li>
      <li>Brief 3</li>
      <li>Long 4</li>
    </ul>
  2. Go to the jQuery Download Builder and select “sortable”. You’ll note that the other required library elements are automatically selected.
  3. Attach the three javascript files downloaded from the builder, and your own javascript file, to your page with the list.
    $(document).ready(function() {
         $("ul.sortable").sortable();
       });

Userful Links