function setOpacity(elem, newValue) { elem.style.opacity = newValue; //IE hacks: elem.style.zoom = 1; //Force hasLayout; needed for filters elem.style.filter = 'alpha(opacity=' + (newValue * 100) + ')'; } var button = document.getElementById('hoverDemo1'); function onMouseOver() { setOpacity(button, 1); } function onMouseOut() { setOpacity(button, .5); } setOpacity(button, .5); //Fade immediately if (button.addEventListener) { button.addEventListener('mouseover', onMouseOver, false); button.addEventListener('mouseout', onMouseOut, false); } else { //More IE Hacks: button.attachEvent('onmouseover', onMouseOver); button.attachEvent('onmouseout', onMouseOut); }
jQuery is an open-source Javascript library that takes the pain out of DOM manipulation, hiding browser differences from developers, and providing a single uniform and consistent API that works in every major browser.
By switching to jQuery, these 20 lines can be reduced to just 4!
$('#hoverDemo2').hover( function() { $(this).css('opacity', 1.0); }, function() { $(this).css('opacity', 0.5); } ).css('opacity', 0.5); //Set initial opacity
Using jQuery, we can also easily add additional features, such as animation:
$('#hoverDemo3').hover( function() { $(this).animate({ opacity: 1.0 }); }, function() { $(this).animate({ opacity: 0.5 }); } ).css('opacity', 0.5); //Set initial opacity
When creating your site, you should use the Development version, which is nicely formatted and commented.
After your site is finished, you should switch to the Production version, which is three times smaller, but impossible to debug.
Actually, you don't even need to download jQuery.
Google graciously provides free hosted versions of jQuery (and other libraries),
so you can just add a <script>
tag that references jQuery from Google's
servers without downloading anything.
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.5.1/jquery.js"> </script>
If you don't remember the URL, just search Google for jQuery Google and you'll find it
in the first result.
You can also find the URLs for Google's hosted libraries at http://ScriptSrc.net.
Before releasing your site, change jquery.js to jquery.min.js to get the production version.
Unlike many other languages, Javascript treats functions as first-class values. Functions can be passed around put in variables, compared, and more.
function createMultiplier(by) { var inner = function(n) { return n * by; } return inner; } var doubler = createMultiplier(2); alert("doubler(2) returns " + doubler(2));
Javascript functions can take any number of arguments, regardless of what parameters the function declared.
Extra arguments can be retrieved from the arguments
keyword, which
is an array-like object.
function showArgs() { alert("I got " + arguments.length + " arguments!\n" + "The third one is " + arguments[2]); } showArgs(); showArgs(1, 2, 3);
Javascript supports objects, which are essentially bags of member values. These members can include simple values, functions, or more objects.
Objects inherit properties (including methods) from prototype
s, which
are similar to classes in classical object-oriented languages.
This feature is beyond the scope of this presentation.
Every value you can work with in Javascript, except for null
and
undefined
, is actually an object, and has properties.
For example, writing 42.toString()
accesses the toString
property (which is inherited from Number.prototype
) and calls the function
that the property points to.
You can create your own objects by writing { }
, and optionally putting
properties between the braces.
var emptyObject = { }; emptyObject.state = "Not empty anymore"; var person = { name: "שמואל", age: 42 }; person.age++; //Happy birthday! alert(person.name + " is " + person.age);
this
Keyword
All Javascript functions take a hidden parameter called the this
keyword.
The this
keyword indicates the context on which the function was invoked.
If you call a function normally, this
will be the global window
object.
If you call a function on an object, this
will be the object that you
called it on.
function whatsThis() { return this.name; } window.name = "the window object"; alert("When called normally, this is " + whatsThis()); var myObject = { name: "MyObject", whatsThis: whatsThis }; alert("When called on an object, this is " + myObject.whatsThis());
Most of jQuery is built around the jQuery object.
A jQuery object is an immutable Javascript object which wraps a set of DOM elements and contains jQuery methods that manipulate the elements.
For those of you who know Java or similar languages, a jQuery object can be thought
of as an instance of the jQuery class, which has a List<DOMElement>
and some methods that do things with the elements.
You can create jQuery objects by calling the jQuery
function.
The jQuery
function takes a variety of parameters and returns a jQuery
object.
jQuery("selector")
jQuery
function takes a CSS selector
as a parameter. It returns a jQuery object with all elements in the document that
match the selector.jQuery(domElement)
jQuery
function with a single DOM element to
create a jQuery object containing that element.
jQuery(this)
will create a jQuery object for the element that fired the event. jQuery(domArray)
jQuery
function can also take an array of DOM elements, creating
a jQuery object containing all of the elements in the array. jQuery()
jQuery
function with no parameters creates an empty jQuery
object with no elements inside of it. jQuery("html string")
jQuery
function with a string containing
(well-formed!) HTML. This will parse the HTML into a set of new DOM elements
and return a jQuery object containing the elements.
In addition to creating jQuery objects, the jQuery
function has an
additional use: it can execute code when the page loads.
Writing jQuery(function() { ... })
will execute the function after
the DOM tree is complete (before images finish loading).
If the DOM tree has already been loaded, the function will be executed immediately.
jQuery(function() { alert("There are " + jQuery('*').length + " DOM elements!"); //More code here... });
When you write Javascript code at the top of an HTML file, it must be wrapped in this call or it will run before the page body has been parsed.
The jQuery
function will be called many times in a typical jQuery-based
page. To make code shorter, jQuery also has a $
function which is aliased
to the jQuery
function.
Thus, all of these examples can be written using $(...)
intead of
jQuery(...)
.
Almost all real-world code uses the $
function.
jQuery supports almost all selectors from the CSS3 specification, regardless of the selectors supported by the browser. jQuery also adds its own custom selectors that are not in CSS.
A complete listing of jQuery selectors is beyond the scope of this presentation;
for more selectors, see
http://api.jquery.com/category/selectors.
#someId
<div id="someId">Lorem ipsum dolor
sit</div>
tagname
<tagname>Lorem ipsum dolor sit</tagname>
.SomeClass
<div class="Header SomeClass">Lorem ipsum dolor sit</div> consectetur adipisicing elit <div class="SomeClass">sed do eiusmod</div>
#someId .SomeClass
<div id="someId">Lorem ipsum dolor sit</div> <div class="SomeClass">sed do eiusmod</div> </div>
Now that we've seen how to create jQuery objects, what can we do with them?
A jQuery object is an array-like object—it can be used as an array
of DOM elements. In other words, all jQuery objects have a length
property
that indicates the number of elements in the set, and numbered properties (from
0
to length - 1
) for the raw DOM elements.
Therefore, you can write $('p')[2]
to get the DOM element for the 3rd
<p>
tag in the page.
Note: This is not a jQuery object; it's a native DOM element. To get a jQuery
object containing the 3rd <p>
tag in the page, write
$('p').eq(2)
.
In addition to acting like arrays, jQuery objects have nearly 150 methods. I'll cover the more useful ones; for complete documentation, see http://API.jQuery.com.
jQuery methods fall into three categories:
These methods retrieve information about an element. They return a Javascript value (typically a string or number) that tells you something useful.
alert($('#slide13 p').text());
These methods modify the elements in the jQuery object. They return the jQuery object that they were called on, allowing you to "chain" method calls—to call multiple methods on the same object.
$('<b> Hi There! </b>') .appendTo("#slide14 p:first") .hide() .fadeIn("slow");
These methods create a new jQuery object containing elements based on the contents of the set you called it on.
var slide = $('#slide15'); var items = slide.find('.Item'); alert(items.length + " items");
Many jQuery methods are properties—they can either return something or change it, depending on what parameters they're passed. Thus, they're both informative methods and action methods.
To get the value of a property, call the method with no parameters. It will return
the value for the first element in the set.
To set the property, call the method and pass the new value as a parameter.
It will set the property for all elements in the set. Like all other action methods,
it will return the jQuery object you called it on, allowing you to chain more methods.
You can also pass a function as the parameter, and jQuery will call the function
for each element in the jQuery object and set the property to whatever the function
returns.
jQuery will pass two parameters to the function: the index (in the set) of the element
it's being called for and the current value of the property for that element.
var items = $('#slide16 p.Item'); items.html( function(index, oldHtml) { return (index + 1) + ": " + oldHtml; } );
.is(selector)
The is
method checks whether at least one element in the set matches
a selector.
The is
method is particularly useful with selectors like :animated
,
:visible
, or :hidden
.
if ($(something).is(":visible"))
.hasClass(class)
The hasClass
method checks whether at least one element in the set
the given class.
if ($(something).hasClass("error"))
.html()
The html
property gets or sets the inner HTML of an element.
alert($('#slide21 p').html());
.text()
The text
property gets or sets the actual text of an element; it will
unescape any HTML entities and will include the text of nested elements.
var p = $('#slide21 li:contains(".text") p'); p.text(function(index, oldText) { return oldText; });
I'm bold or italic!
Isn't that boring?
.width()
/ .height()
These properties give the inner dimensions an element, in pixels.
Setting these properties will directly modify the CSS height
and
width
properties.
.val()
The val
property gives the current value of a form element (<input>
,
<select>
, <option>
, or <textarea>
).
Typically, this property maps directly to the native DOM element's value
property.
However, <select>
elements don't have a value
property
(only selectedIndex
). For <select>
elements, the
val
property will find the selected <option>
and return
its value.
For multi-select listboxes, val
will return an array of the selected
values.
.css()
.attr()
These methods take an additional parameter for the name of the property to get or set.
alert($('#slide22 .CodeBox').attr('animation'));
$('#slide22 .CodeBox').attr('animation', 'explode');
These methods can also take an object of properties to set.
$('#slide22 p').css({ fontStyle: "italic", color: "Green" });
.addClass(classname)
/ .removeClass(classname)
Adds or removes CSS classes from the elements in the set.
$('.Active').removeClass("Active"); $(something).addClass("Active");
.append(stuff)
Appends stuff to the end of every element in the set. stuff
can
be a jQuery object, a DOM element, a string of HTML, or a function that generates
one of the above.
$('#slide23 p.Item').append(" ☺");
jQuery can add event handlers using the .bind()
, which takes one or
more event names and a callback to handle the event.
$('#eventDemo1').bind("mousemove", function(e) { $(this).text(e.pageX + ", " + e.pageY); });
jQuery also has helper methods for common events:
$('#eventDemo2').keyup(function() { $("#echoer").text(this.value); });
$('#hoverDemo4').hover( function() { $(this).css('opacity', 1.0); }, function() { $(this).css('opacity', 0.5); } ).css('opacity', 0.5); //Set initial opacity
There are two common mistakes that people make when creating event handlers.
$('#eventDemo3').click(alert("Clicked!"));
This code calls alert
immediately, then passes its return value
to the jQuery click
method.
It should be written like this, passing a function expression that calls alert
to the click
method.
$('#eventDemo4').click(function() { alert("Clicked!"); });
var container = $('#buttonBox1').empty(); for (var i = 1; i <= 9; i++) { $('<button>' + i + '</button>') .click(function() { alert(i); }) .appendTo(container); }
This code captures the i
variable in the function expression. However,
because Javascript doesn't have block scoping, the code shares a single i
variable among all of the callbacks.
The callbacks are only run after the for
loop finishes (when the user
clicks the buttons), when i
is 10
.
var container = $('#buttonBox2').empty(); for (var i = 1; i <= 9; i++) { createButton(i); } function createButton(i) { $('<button>' + i + '</button>') .click(function() { alert(i); }) .appendTo(container); }
To fix this code, I move the callbacks to a separate method which takes i
as a parameter. Since each callback now comes from a different method invocation,
they don't share the same variable.
Another common problem with jQuery events is that event handlers are only added to the elements currently in the set. If new similar elements are added later, they won't get event handlers unless they're added separately.
To solve this problem, jQuery supports live events, which bind handlers to all elements that match a selector, no matter when they were created.
$('#liveBox button').live('click', function() { alert("Congratulations!\nYou clicked a button!"); });
After running this code, all elements that match the selector will have their
click
event handled.
$('#liveBox').append('<button></button>');
You can animate a CSS property by calling the animate
method.
var p = $('#slide27 p:visible'); p.animate( { fontSize: 50 }, 2500, //milliseconds function() { alert('Done!\n\n' + $(this).text()); } );
Animations are queued on each element, meaning that if you call animate
twice, the second animation will run after the first one finishes.
var p = $('#slide27 p:visible'); p.animate({ fontSize: 5 }) .animate({ fontSize: 25 });
Any numeric property can be animated.
jQuery UI adds the ability to animate colors.
.find(selector)
.filter(selector)
.children(selector)
.parent()
.eq(index)
.closest(selector)
jQuery also has an AJAX library, which hides the differences in XmlHttpRequest
s
between browsers.
To send an AJAX request, call $.ajax
:
$.ajax({ url: "/something", type: "POST", success: function(data, status) { ... }, error: function() { ... } });
AJAX is asynchronous. When you send an AJAX request, the next line of code will
execute immediately, before the server sends a reply. Therefore, any code that needs
the server's reply must go in the success
callback.
For security reasons, AJAX requests can only be sent to URLs in the same domain that the page is running on.
To send AJAX requests to a different website, you can use the JSONP protocol. (assuming
that the other server supports it)
jQuery includes a JSONP client in the getJSON method:
$.getJSON( "http://api.geonames.org/findNearByWeatherJSON" + "?lat=40.849557&lng=-73.929857&username=demo&callback=?", function(data) { var celsius = data.weatherObservation.temperature; var fahrenheit = 32 + (212 - 32) / 100 * celsius; alert("It's " + Math.round(fahrenheit) + "° outside!"); } );
When you make a JSONP request, jQuery will create a callback function with a unique
name and add a callback=name
parameter to the query string.
It will then create <script>
tag pointing to the URL.
The server-side script is expected to return Javascript code that calls the function
specified by the callback
parameter and passes it the requested data.
In this case, jQuery will generate a URL like http://api.geonames.org/findNearByWeatherJSON?lat=40.849557&lng=-73.929857&username=demo&callback=jQuery1510697_1300041015100&_=1300041017078
.
This URL returns Javascript code like jQuery1510697_1300041015100({"weatherObservation":
{ ... }});
.
When the new <script>
tag executes, this code calls the generated
jQuery1510697_1300041015100
method, which will in turn call the callback
passed to getJSON
.
You can add your own methods to the jQuery object by adding them to jQuery.fn
:
jQuery.fn.double = function() { this.append(this.html()); return this; }; var p = $('#slide30 p.Item:first'); p.double();
These methods are called on jQuery objects, so the this
keyword will
refer to the jQuery object it was called on.
Thus, I can write this.html()
to get the HTML source of the object
that the double()
method was called on.
In order to allow method chaining, plugin methods should end with return this
;
this allows you to call other methods after calling the plugin.
Obviously, if you create a plugin that returns information, it should not return
this
; it should return whatever information it's supposed to. (Like an
informative method)
jQuery also has a wide ecosystem of free plugins.
Some of the more popular ones include:
Always check the documentation!
jQuery's documentation is very thorough and understandable, and has lots of examples.
jsFiddle is an HTML sandbox which allows you to quickly try out HTML, CSS, and Javascript code without creating files on your hard disk.
You can type arbitrary code (with syntax highlighting) and execute it on the fly. You can also save your code to a permanent URL so that you can come back to it later or share it with someone else.
Visual Studio is a great all-around development tool.
Using a vsdoc
file, you can even get full IntelliSense for jQuery.
Ordinarily, Visual Studio Professional costs $800, but it's available for free to
students through Microsoft's DreamSpark program.
Just go to http://DreamSpark.com
and follow the instructions to verify that you're a student.
StackOverflow is the world's largest online developer community. You can ask programming
related questions there and (typically) get an answer within minutes.
Unlike ExpertsExchange, it's completely free.