Except where otherwise noted, the contents of this document are Copyright 2012 Marty Stepp, Jessica Miller, Victoria Kirst and Roy McElmurry IV. 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.
var things = ['a', 'b', 'c', 'd', 'e']; for (idx in things) { console.log(idx + ', ' + things[idx]); }
0, a 1, b 2, c 3, d 4, e
var myfunc = function(a, x) {
return a * b;
};
var x = myfunc(2, 3); // 6
function apply(a, b, f) {
return f(a, b);
}
var x = apply(2, 3, myfunc); // 6
function getAlert(str) { return function() { alert(str); } } var myAlertFunc = getAlert("What's up!");
function getAlert(str) {
var prefix = "Roy: ";
return function() {
alert(prefix + str);
}
}
var myAlertFunc = getAlert("What's up!");
myAlertFunc(); // "Roy: What's up!"
.
syntaxvar x = { 'a': 97, 'b': 98, 'c': 99, 'd': 199, 'mult': function(a, b) { return a * b; } };
var things = {'a': 97, 'b': 98, 'c': 99 }; for (key in things) { console.log(key + ', ' + things[key]); }
a, 97 b, 98 c, 99
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:
JavaScript is a powerful language, but it has many flaws:
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js" type="text/javascript"></script>
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.
window.onload = function() {
// do stuff with the DOM
}
$(document).ready(function() {
// do stuff with the DOM
});
$(function() {
// do stuff with the DOM
});
We will be working on a bouncing images example.
document
and other DOM objects (* = HTML5):
name | description |
---|---|
getElementById
|
returns array of descendents with the given tag, such as "div"
|
getElementsByTagName
|
returns array of descendents with the given tag, such as "div"
|
getElementsByName
|
returns array of descendents with the given name attribute (mostly useful for accessing form controls)
|
querySelector *
|
returns the first element that would be matched by the given CSS selector string |
querySelectorAll *
|
returns an array of all elements that would be matched by the given CSS selector string |
highlight all paragraphs in the document:
var allParas = document.querySelectorAll("p"); for (var i = 0; i < allParas.length; i++) { allParas[i].style.backgroundColor = "yellow"; }
<body> <p>This is the first paragraph</p> <p>This is the second paragraph</p> <p>You get the idea...</p> </body>
highlight all paragraphs inside of the section with ID "address"
:
var addrParas = document.querySelectorAll("#address p"); for (var i = 0; i < addrParas.length; i++) { addrParas[i].style.backgroundColor = "yellow"; }
<p>This won't be returned!</p>
<div id="address">
<p>1234 Street</p>
<p>Atlanta, GA</p>
</div>
// identifying a single elemnt var list = document.getElementById("mylist"); // identifying a group of elements var specials = document.querySelectorAll("li.special");
The $
aka jQuery
function selects elements from the DOM using most any CSS selector.
// id selector
var elem = $("#myid");
// group selector
var elems = $("#myid, p");
// context selector
var elems = $("#myid < div p");
// complex selector
var elems = $("#myid < h1.special:not(.classy)");
DOM method | jQuery equivalent |
---|---|
getElementById("id")
|
$("#id")
|
getElementsByTagName("tag")
|
$("tag")
|
getElementsByName("somename")
|
$("[name='somename']")
|
querySelector("selector")
|
$("selector")
|
querySelectorAll("selector")
|
$("selector")
|
p
tags that have no children, but only if they don't have a class of ignore
div
tags with a child that has a class of special
h1
, h2
, h3
, h4
, h5
, h6
)li
.#square
and periodically change it's position in a random direction.jQuery
object or the $
function depending on the context$
function always (even for ID selectors) returns an array-like object called a 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];
$
as a wrapper$
adds extra functionality to DOM elements$
will give it the jQuery upgrade
// convert regular DOM objects to a jQuery object
var elem = document.getElementById("myelem");
elem = $(elem);
var elems = document.querySelectorAll(".special");
elems = $(elems);
querySelectorAll()
and querySelector()
on any DOM
object.var list = document.getElementsByTagName("ul")[0]; var specials = list.querySelectorAll('li.special');
find
/ context parameterjQuery 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");
<p> This is a paragraph of text with a <a href="/path/page.html">link in it</a>. </p>
every node's DOM object has the following properties:
name(s) | description |
---|---|
firstChild , lastChild
|
start/end of this node's list of children |
childNodes
|
array of all this node's children |
nextSibling , previousSibling
|
neighboring nodes with the same parent |
parentNode
|
the element that contains this node |
<p id="foo">This is a paragraph of text with a <a href="/path/to/another/page.html">link</a>.</p>
<div> <p> This is a paragraph of text with a <a href="page.html">link</a>. </p> </div>
div
above have?"\n\t"
(before/after the paragraph)a
tag?
#box
childrenbox
element and change their position.
var elems = document.querySelectorAll("li");
for (var i = 0; i < elems.length; i++) {
var e = elems[i];
// do stuff with e
}
$("li").each(function(idx, e) {
// do stuff with e
});
for each
loop on either because they are not technically arrays, just array-like objects.
$("li").each(function(idx, e) {
// do stuff with e
});
false
to exit the loop early$
if we want
$("li").each(function(idx, e) {
e = $(e);
// do stuff with e
});
this
keyword refers to the same selected element as e, so this is better jQuery
$("li").each(function() {
// do stuff with this
});
DOM nodes have fields that correspond to the attributes in HTML tags. There are a few exceptions
HTML attributes | DOM fields |
---|---|
title |
.title |
id |
.id |
class |
.className |
style="prop: value" |
.style.prop = value |
function highlightField() {
// turn text yellow and make it bigger
var elem = document.getElementById("id");
if (!elem.className) {
elem.className = "highlight";
} else if (elem.className.indexOf("invalid") < 0) {
elem.className += " highlight";
}
}
className
property corresponds to HTML class
attributeclassName
is just a string, not an array like we would want
function highlightField() {
// turn text yellow and make it bigger
if (!$("#myid").hasClass("invalid")) {
$("#myid").addClass("highlight");
}
}
addClass
, removeClass
, hasClass
, toggleClass
manipulate CSS classesclassName
DOM property, but don't have to manually split by spaces
<button id="clickme">Color Me</button>
window.onload = function() { document.getElementById("clickme").onclick = changeColor; }; function changeColor() { var clickMe = document.getElementById("clickme"); clickMe.style.color = "red"; }
Property | Description |
---|---|
style
|
lets you set any CSS style property for an element |
camelCasedNames
backgroundColor
, borderLeftWidth
, fontFamily
.style
when setting styles
var clickMe = document.getElementById("clickme");clickMe.color = "red";clickMe.style.color = "red";
likeThis
, not like-this
clickMe.style.font-size = "14pt";clickMe.style.fontSize = "14pt";
clickMe.style.width = 200;clickMe.style.width = "200px"; clickMe.style.padding = "0.5em";
<button id="clickme">Click Me</button>
window.onload = function() { document.getElementById("#clickme").onclick = biggerFont; }; function biggerFont() { var size = parseInt(document.getElementById("#clickme").style.fontSize); size += 4; document.getElementById("#clickMe").style.fontSize = size + "pt"; }
style
property lets you set any CSS style for an element
function biggerFont() {
// turn text yellow and make it bigger
var size = parseInt($("#clickme").css("font-size"));
$("#clickme").css("font-size", size + 4 + "pt");
}
css
function of the jQuery object allows reading pre-existing stylesfont-size
syntax instead of fontSize
css(property)
gets the property value, css(property, value)
sets the property value// bad!$("#main").css("top", $("#main").css("top") + 100 + "px");
"200px" + 100 + "px"
, "200px100px"
// correct
$("#main").css("top", parseInt($("#main").css("top")) + 100 + "px");
square
directly in the center of it's parent.#square
change direction when it reaches the boundary of it's parent.function okayClick() {this.style.color = "red";this.className = "highlighted"; }
.highlighted { color: red; }
<ul> <li style="font-size: 10px">10px font size</li> <li style="font-size: 20px">20px font size</li> <li style="font-size: 30px">30px font size</li> </ul>
$("li").css("font-size"); // returns '10px'
$("li").css("font-size", "15px"); // sets all selected elements to '8px'
<ul> <li style="font-size: 15px">10px font size</li> <li style="font-size: 15px">20px font size</li> <li style="font-size: 15px">30px font size</li> </ul>
Many jQuery object methods are overloaded
$("#myid").css(propertyName);
$("#myid").css(propertyName, value);
$("#myid").css({ 'propertyName1': value1, 'propertyName2': value2, ... });
$("#myid").css(propertyName, function(idx, oldValue) { return newValue; });
What do you think the multi-modifier syntax is?
// bad jQuery$("#main").css("top", parseInt($("#main").css("top")) + 100 + "px");
$("#main").css("top", function(idx, old) {
return parseInt(old) + 100 + "px";
}); // good jQuery
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 |
$("#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 :(
div
s with a class of square
to the html.background-color
of each square when it hits a wall.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
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 |
innerHTML
hackingWhy not just code the previous example this way?
document.getElementById("myid").innerHTML += "<p>A paragraph!</p>";
"
and '
document.getElementById("myid").innerHTML += "<p style='color: red; " + "margin-left: 50px;' " + "onclick='myOnClick();'>" + "A paragraph!</p>";
name | description |
---|---|
document.createElement("tag")
|
creates and returns a new empty DOM node representing an element of that type |
document.createTextNode("text")
|
creates and returns a text node containing given text |
// create a new <h2> node
var newHeading = document.createElement("h2");
newHeading.innerHTML = "This is a heading";
newHeading.style.color = "green";
Every DOM element object has these methods:
name | description |
---|---|
appendChild(node)
|
places given node at end of this node's child list |
insertBefore(new, old)
|
places the given new node in this node's child list just before old child
|
removeChild(node)
|
removes given node from this node's child list |
replaceChild(new, old)
|
replaces given child with new node |
var p = document.createElement("p"); p.innerHTML = "A paragraph!"; document.getElementById("myid").appendChild(p);
var bullets = document.getElementsByTagName("li"); for (var i = 0; i < bullets.length; i++) { if (bullets[i].innerHTML.indexOf("child") >= 0) { bullets[i].parentNode.removeChild(bullets[i]); } }
removeChild
method to remove the given child from the page
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();
.square div
s to the page using jQuery.div
s to be img
tags with a src
of laughing_man.jpg.$("<p id='myid' class='special'>My paragraph is awesome!</p>")
$("<p>") .attr("id", "myid") .addClass("special") .text("My paragraph is awesome!");
$("<p>", { "id": "myid", "class": "special", "text": "My paragraph is awesome!" });
$
function signatures$(function);
$("selector", [context]);
$(elements);
$("<html>", [properties]);
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); }
$("#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); });
$("#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"); } }));