5 Things You Might Not Know about jQuery
jQuery is a very powerful library, but some of its powerful features are obscure, and unless you've read the jQuery source code, or my new book jQuery Pocket Reference, you may not know about them. This article excerpts that book to describe five useful features of jQuery that you might not know about.
- You don't have to use
$(document).ready() anymore, though you'll still see plenty of code out there that does. If you want to run a function when the document is ready to be manipulated, just pass that function directly to $().
attr() is jQuery’s master attribute-setting function, and you can use it to set things other than normal HTML attributes. If you use the attr() method to set an attribute named “css”, “val”, “html”, “text”, “data”, “width”, “height”, or “offset”, jQuery invokes the method that has the same name as that attribute and passes whatever value you specified as the argument.
(Edit: Thanks to niyazpk and jerone for letting me know, in the comments, that the paragraph above was wrong. The special property names only work in the case described below, which I've also updated. Sorry for my confusion!)
You probably already know that you can pass a tagname to $() to create an element of that type, and that you can pass (as a second argument) an object of attributes to be set on the newly created element. This second argument can be any object that you would pass to the attr() method, but in addition, if any of the properties have the same name as the event registration methods, the property value is taken as a handler function and is registered as a handler for the named event type. Similarly, if any of the properties has the name “css”, “val”, “html”, “text”, “data”, “width”, “height”, or “offset”, then the value of that property is passed to the method with the same name as the property. The following code, for example, creates a new element, sets three HTML attributes of it, registers an event handler for it, and sets a CSS style attribute on it:
var image = $("<img>", {
src: image_url,
alt: image_description,
className: "translucent_image",
click: function() {$(this).css("opacity", "50%");},
css: { border: "dotted red 3px" }
});
- jQuery defines simple methods like
click() and change() for registering event handlers and also defines a more general event handler registration method named bind(). An important feature of bind() is that it allows you to specify a namespace (or namespaces) for your event handlers when you register them. This allows you to define groups of handlers, which comes in handy if you later want to trigger or de-register all the handlers in a particular group. Handler namespaces are especially useful for programmers who are writing libraries or modules of reusable jQuery code. Event namespaces look like CSS class selectors. To bind an event handler in a namespace, add a period and the namespace name to the event type string:
// Bind f as a mouseover handler in namespace "myMod"
$('a').bind('mouseover.myMod', f);
If your module registered all event handlers using a namespace, you can easily use unbind() to de-register them all:
// Unbind all mouseover and mouseout handlers
// in the "myMod" namespace
$('a').unbind("mouseover.myMod mouseout.myMod");
// Unbind handlers for any event in the myMod namespace
$('a').unbind(".myMod");
- jQuery defines simple animation functions like
fadeIn(), and also defines a general-purpose animation method named animate(). The queue property of the options object you pass to animate() specifies whether the animation should be placed on a queue and deferred until pending and previously queued animations have completed. By default, animations are queued, but you can disable this by setting the queue property to false. Unqueued animations start immediately. Subsequent queued animations are not deferred for unqueued animations. Consider the following code:
$("img").fadeIn(500)
.animate({"width":"+=100"},
{queue:false, duration:1000})
.fadeOut(500);
The fadeIn() and fadeOut() effects are queued, but the call to animate() (which animates the width property for 1000ms) is not queued. The width animation begins at the same time the fadeIn() effect begins. The fadeOut() effect begins as soon as the fadeIn() effect ends—it does not wait for the width animation to complete.
- jQuery fires events of type “ajaxStart” and “ajaxStop” to indicate the start and stop of Ajax-related network activity. When jQuery is not performing any Ajax requests and a new request is initiated, it fires an “ajaxStart” event. If other requests begin before this first one ends, those new requests do not cause a new “ajaxStart” event. The “ajaxStop” event is triggered when the last pending Ajax request is completed and jQuery is no longer performing any network activity. This pair of events can be useful to show and hide a “Loading...” animation or network activity icon. For example:
$("#loading_animation").bind({
ajaxStart: function() { $(this).show(); },
ajaxStop: function() { $(this).hide(); }
});
These “ajaxStart” and “ajaxStop” event handlers can be bound to any document element: jQuery triggers them globally rather than on any one particular element.
Tags:
1
19 Replies
The first example for the 2nd point is wrong:
//The following two lines have the same effect, for example:
$('pre').attr("css", {backgroundColor:"gray"})
$('pre').css({backgroundColor:"gray"})
Not correct. The first line will create an attribute called 'css' while the second line will change the 'style' attribute. The author probably meant something like:
$('pre').attr("style", {backgroundColor:"gray"})
$('pre').css({backgroundColor:"gray"})
...but even these two lines are not exactly the same. The first one will reset the style attribute to the given value while the second line will just change the backgroundColor value in the style attribute.
Could you please post an example for point #1?
The second example doesn't work for me.
var image = $("").appendTo("body"); //Nothing appended to body.
I think it should be:
var image = $("<img>").appendTo("body"); //img node appended to body.
Adolph,
You're right. My angle brackets got eaten. Sorry.
Scott,
All I mean is you can pass a function directly to $(). Many people do this all the time. Some coders still seem to be using the older ready() method.
Niyazpk,
It looks wrong, but it isn't. Try it out. In 1.4 (at least) the attribute name "css" is special. Setting it with attr() actually calls the css() method.
Can you please discuss a bit more about #3 and using name-spacing in event-handlers? It's a new concept to me, and I'm very curious about it, how it would be used, etc. Or perhaps direct us to articles on the concept?
the use of $().ready(handler) is not recommended by the official jQuery API Docs
$().ready(handler) //(this is not recommended)*
Is there any specific detail on why we should be using it?
* jQuery API Docs - Ready Event
lelando,
There is more about event handler namespaces in my book!
mrpollo,
You misunderstand me. I'm saying the same thing as the jQuery docs here. If you have a function f and you want that function to be invoked when the document is ready, just call $(f). There are jQuery programmers who are still calling $(document).ready(f). That is no longer necessary.
I disagree at 1st case , sometime you still need $(document).ready()
<script>
$(document).ready(function(){
$("#test").css("background","red");
});
</script>
<div id="test"> test div </div>
if remove $(document).ready() you see it.
jdeper,
I think the author meant that you can directly invoke the function without calling $(document).ready explicitly. The code that you have used as an example will also work with Tip #1 like so:
$(function(){
$("#test").css("background","red");
})
This will still run on the ready event even though it hasn't been explicitly called to do so.
How long have you been able to use $() and pass in a function without have to specify $(document).ready() because I've been using that shorthand for quite sometime but you say "You don't have to use $(document).ready() anymore"? It also seems like quite a lot of people were unaware of this.
Also, thanks for the tip on queue: false, I was not aware of this.. very useful.
@David - *which* book? :-)
jdeeper,
aidifbk is correct. All I mean is that you should pass your "onload" function to $() instead of $(document).ready(). Thanks aidifbk for clarifying.
benjreinhart,
I'm not sure how long $() has worked as an alternative to $(document).ready(). I'm pretty sure it worked in 1.3. You're right that "anymore" is kind of misleading. But I share your surprise at how many are unaware of it, which is why I put it at the top of my list here! It might mean that jQuery needs better documentation (like jQuery Pocket Reference :-) or it might have something to do with how much we developers have come to rely on (out-of-date and poorly written) articles on the web to learn new technologies... But that is a rant for another time!
lelando,
I mean my new jQuery book, _jQuery Pocket Reference_. This article is a promo for, and consists of excerpts from, that book. And I'm not trying to be coy about not revealing event namespace details here. Its just that I've got to get back to work on Javascript: The Definitive Guide.
$(function(){ ... }); is a shortcut for: $(document).ready(function(){ ... });It does the same, only shorter.
The second tip, I can't get to work. I put all available suggestion online, but it doesn't work: http://jsfiddle.net/jerone/hZjTd/1/
Jerone: You're right. Point 2 doesn't work.
Niyazpk: you told me I was wrong, but I didn't believe you. My apologies!
This was based on a mis-reading of the jQuery source code and, obviously, a failure to test this example.
css, val, text, html, etc. do work as property names when you are creating new elements with $ and passing an object as the second argument to configure them.
For example, to extend the example that Jernone linked to:
$(document.body).append($("<p>", {
id: "test7",
text: "test 7",
css: { backgroundColor: "red" },
click: function() { alert('hello world'); }
}));
Try it here: http://jsfiddle.net/hZjTd/2/
I'll fix the article.
"But I share your surprise at how many are unaware of it, which is why I put it at the top of my list here! It might mean that jQuery needs better documentation (like jQuery Pocket Reference :-) or it might have something to do with how much we developers have come to rely on (out-of-date and poorly written) articles on the web to learn new technologies..."
Or maybe they should just read a book on jQuery, I learned that from jQuery: Novice to Ninja, and I believe HTML5 and CSS3 from pragmatic programmers include that tip.
Ohhh well...
Even considering the fact you write less with $(function() { /* code here */ });, actually the best option, IMO is jQuery(function($) { /* code here */ });
This way you create a local var $ making it an instance of jQuery. Why? to prevent external conflicts with other javascript libs as Prototype and others.
You don't write that less, but you do even more.
The external $ is just a reference to jQuery variable, but you won't find another libs overwriting the jQuery name.
About
> 1) You don't have to use $(document).ready() anymore
Is it just a matter of more concise code or does it have a side effect?
"anymore"? Since what version of jQuery?
in second example must be css("opacity", "0.5") because css("opacity", "50%") don`t work
Hi,
About the question regarding the use of $().ready(handler). The syntax has been deprecated since jQuery 1.4. Please refer to the full release notes.
Refulz PHP
|