Web Programming Step by Step, 2nd Edition

Lecture TBD: jQuery

Reading: none

Except where otherwise noted, the contents of this document are Copyright 2012 Marty Stepp, Jessica Miller, and Victoria Kirst. All rights reserved. Any redistribution, reproduction, transmission, or storage of part or all of the contents in any form is prohibited without the author's expressed written permission.

Valid HTML5 Valid CSS

The jQuery Library

There is no chapter about jQuery in our course book. Learning jQuery will be an exercise in your ability to navigate online APIs and documentation:

Problems with JavaScript

JavaScript is a powerful language, but it has many flaws:

jQuery framework

<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"
 type="text/javascript"></script>

jQuery Design Principles

jQuery is so powerful in part because of these design principles

window.onload

We cannot use the DOM before the page has been constructed. jQuery gives us a more compatibile way to do this.

Aspects of the DOM and jQuery

jQuery Selectors

jQuery / DOM comparison

DOM method jQuery equivalent
getElementById("id") $("#id")
getElementsByTagName("tag") $("tag")
getElementsByName("somename") $("[name='somename']")
querySelector("selector") $("selector")
querySelectorAll("selector") $("selector")

jQuery Terminology

the jQuery function
refers to the global jQuery object or the $ function depending on the context
a jQuery object
the object returned by the jQuery function that often represents a group of elements
selected elements
the DOM elements that you have selected for, most likely by some CSS selector passed to the jQuery function and possibly later filtered further

The jQuery object

// false
document.getElementById("id") == $("#myid");
document.querySelectorAll("p") == $("p");

// true
document.getElementById("id") == $("#myid")[0];
document.getElementById("id") == $("#myid").get(0);

document.querySelectorAll("p")[0] == $("p")[0];

Using $ as a wrapper

// convert regular DOM objects to a jQuery object
var elem = document.getElementById("myelem");
elem = $(elem);

var elems = document.querySelectorAll(".special");
elems = $(elems);

DOM context identification

DOM tree
var list = document.getElementsByTagName("ul")[0];
var specials = list.querySelectorAll('li.special');

find / context parameter

jQuery gives two identical ways to do contextual element identification

var elem = $("#myid");

// These are identical
var specials = $("li.special", elem);
var specials = elem.find("li.special");

jQuery traversal methods

Looping over the DOM

Inside the jQuery each loop

$("li").each(function(idx, e) {
	// do stuff with e
});
$("li").each(function(idx, e) {
	e = $(e);
	// do stuff with e
});
$("li").each(function() {
	// do stuff with this
});

Getting/setting CSS classes in jQuery

function highlightField() {
	// turn text yellow and make it bigger
	if (!$("#myid").hasClass("invalid")) {
		$("#myid").addClass("highlight");
	}
}

Accessing styles in jQuery

function biggerFont() {
	// turn text yellow and make it bigger
	var size = parseInt($("#clickme").css("font-size"));
	$("#clickme").css("font-size", size + 4 + "pt");
}

Common bug: incorrect usage of existing styles

// bad!
$("#main").css("top", $("#main").css("top") + 100 + "px");

jQuery method behavior

jQuery method parameters

Many jQuery object methods are overloaded

getter syntax:
$("#myid").css(propertyName);
setter syntax:
$("#myid").css(propertyName, value);
multi-setter syntax:
$("#myid").css({
	'propertyName1': value1,
	'propertyName2': value2,
	...
	});
modifier syntax:
$("#myid").css(propertyName, function(idx, oldValue) {
	return newValue;
});

What do you think the multi-modifier syntax is?

common jQuery mistake

// bad jQuery
$("#main").css("top", parseInt($("#main").css("top")) + 100 + "px");

jQuery method returns

When there is no other return to make, jQuery methods return the same jQuery object back to you

method return type
$("#myid"); jQuery object
$("#myid").children(); jQuery object
$("#myid").css("margin-left"); String
$("#myid").css("margin-left", "10px"); jQuery object
$("#myid").addClass("special"); jQuery object

jQuery chaining


$("#main").css("color", "red");
$("#main").attr("id", "themainarea");
$("#main").addClass("special");

The implictly returned jQuery object allows for chaining of method calls.

$("img")
	.css("color", "red")
	.addClass("special")
	.src = "foo.png";

Expression return value at each line:

// [<img />, ...]
// [<img style="color: red" />, ...]
// [<img class="special" style="color: red" />, ...]
// cannot chain further because this is an assignment :(

jQuery attr() function

$("img")				// poor jQuery style
	.css("color", "red")
	.addClass("special")
	.src = "foo.png";
$("img")				// good jQuery style
	.css("color", "red")
	.addClass("special")
	.attr("src", "foo.png");
	// we could chain further right here

More node manipulation with jQuery

Suppose you already have a jQuery object, e.g. $("#myid")

jQuery method functionality
.hide() toggle CSS display: none on
.show() toggle CSS display: none off
.empty() remove everything inside the element, innerHTML = ""
.html() get/set the innerHTML without escaping html tags
.text() get/set the innerHTML, HTML escapes the text first
.val() get/set the value of a form input, select, textarea, ...
.height() get/set the height in pixels, returns a Number
.width() get/set the width in pixels, return a Number

jQuery manipulation methods

Create nodes in jQuery

The $ function to the rescue again

var newElement = $("<div>");
$("#myid").append(newElement);

jQuery programmers typically 1 line it

$("#myid").append($("<div>"));

The previous example becomes this with jQuery


var bullets = document.getElementsByTagName("li");
for (var i = 0; i < bullets.length; i++) {
	if (bullets[i].innerHTML.indexOf("children") >= 0) {
		bullets[i].parentNode.removeChild(bullets[i]);
	}
}
$("li:contains('child')").remove();

Creating complex nodes in jQuery

The terrible way, this is no better than innerHTML hacking
$("<p id='myid' class='special'>My paragraph is awesome!</p>")
The bad way, decent jQuery, but we can do better
$("<p>")
	.attr("id", "myid")
	.addClass("special")
	.text("My paragraph is awesome!");
The good way
$("<p>", {
	"id": "myid",
	"class": "special",
	"text": "My paragraph is awesome!"
});

jQuery $ function signatures

Responding to the page ready event
$(function);
Identifying elements
$("selector", [context]);
Upgrading DOM elements
$(elements);
Creating new elements
$("<html>", [properties]);

DOM example

Here is what it might look like if you tried to insert an image before each special span tag in a div using the DOM's API.

var spans = document.querySelectorAll("#ex1 span.special");
for (var i = 0; i < spans.length; i++) {
	var img = document.createElement("img");
	img.src = "images/laughing_man.jpg";
	img.alt = "laughing man";
	img.style.verticalAlign = "middle";
	img.style.border = "2px solid black";
	img.onclick = function() {
		alert("clicked");
	}
	spans[i].insertBefore(img, spans[i].firstChild);
}
Special Special Not Special Special Not Special

Poor jQuery example

$("#ex2 span.special").each(function(i, elem) {
	var img = $("<img>")
		.attr("src", "images/laughing_man.jpg")
		.attr("alt", "laughing man")
		.css("vertical-align", "middle")
		.css("border", "2px solid black")
		.click(function() {
			alert("clicked");
		});
	$(elem).prepend(img);
});
Special Special Not Special Special Not Special

Good jQuery example

$("#ex3 span.special").prepend($("<img>", {
	"src": "images/laughing_man.jpg",
	"alt": "laughing man",
	"css": {
		"vertical-align": "middle",
		"border": "2px solid black"
	},
	"click": function() {
		alert("clicked");
	}
}));
Special Special Not Special Special Not Special