Skip to content

Commit 55bf68c

Browse files
committed
Add article on the jQuery object as requested in issue jquery#95
1 parent aaf6301 commit 55bf68c

File tree

1 file changed

+188
-0
lines changed

1 file changed

+188
-0
lines changed
+188
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,188 @@
1+
---
2+
level : beginner
3+
title : The jQuery Object
4+
attribution: Mike Pennisi
5+
github : jugglinmike
6+
---
7+
Presumably, if you're reading this, you are curious about the thing that jQuery returns when you create new elements (or select existing ones).
8+
This curiosity is a great first step, because a first glance, the jQuery object may seem to be an array of DOM elements.
9+
It has a collection of DOM elements, some familiar array functions, and a `length` property, after all.
10+
Actually, the jQuery object is more complicated than that.
11+
12+
### What is a DOM element, anyway?
13+
14+
A DOM element is a "piece" of a web page.
15+
It can contain text and/or other DOM elements.
16+
It is described by a type (i.e. "div", "a", "p", etc.) and any number of attributes (i.e. "src", "href", "class", etc.).
17+
For a more thorough description, please refer to [the office specification from the W3C](http://www.w3.org/TR/DOM-Level-2-Core/core.html#ID-745549614).
18+
19+
Elements have properties like any JavaScript object.
20+
Among these properties are attributes like `tagName` and methods like `appendChild`.
21+
These properties are the only way to interact with the web page via JavaScript.
22+
23+
### So why not just put the elements in an array?
24+
25+
It turns out that working directly with DOM elements can be quite awkward.
26+
The jQuery object defines [a ton](http://api.jquery.com/) of methods to smooth out the experience for developers.
27+
For example:
28+
29+
*Compatability*
30+
The implementation of element methods varies across browser vendors and versions.
31+
Imagine that you wanted to set the inner HTML of a `tr` element stored in `target`. You might write:
32+
33+
<javascript caption="Setting the inner HTML with the native DOM API">
34+
var target = document.getElementById("target");
35+
target.innerHTML = "<td>Hello <b>World</b>!</td>";
36+
</javascript>
37+
38+
This works in most cases, but it will fail in most versions of Internet Explorer.
39+
In that case, the [recommended approach](http://www.quirksmode.org/dom/w3c_html.html) is to use pure DOM methods instead.
40+
By wrapping the `target` element in a jQuery object, these edge cases are taken care of, and the expected result is acheived in all supported browsers:
41+
42+
<javascript caption="Setting the inner HTML with jQuery">
43+
var target = document.getElementById("target");
44+
$( target ).html( "<td>Hello <b>World</b>!</td>");
45+
</javascript>
46+
47+
*Convenience*
48+
There are also a lot of common DOM manipulation use cases that are awkward to accomplish with pure DOM methods.
49+
For instance, if you want to insert the element stored in `newElement` after the element stored in `target`, you have to write:
50+
51+
<javascript caption="Inserting a new element after another with the native DOM API">
52+
var target = document.getElementById("target");
53+
var newElement = document.createElement("div");
54+
target.parentNode.insertBefore( target.nextSibling, newElement )
55+
</javascript>
56+
57+
By wrapping the `target` element in a jQuery object, you can accomplish the same task in a much simpler manner:
58+
59+
<javascript caption="Inserting a new element after another with jQuery">
60+
var target = document.getElementById("target");
61+
var newElement = document.createElement("div");
62+
$( target ).after( newElement );
63+
</javascript>
64+
65+
If you're in the business of getting things done (and I suspect that you are), then these details are simply "gotchas" that stand between you and your goals.
66+
67+
### Sounds good. Now how do I get stuff in there?
68+
69+
If you pass a CSS selector to the jQuery function, the result will be a jQuery object wrapping any element(s) that match this selector.
70+
For instance, by writing
71+
72+
<javascript caption="Selecting all 'h1' tags">
73+
var allHeaders = $("h1");
74+
</javascript>
75+
76+
`headers` is now a jQuery element containing *all* the `<h1>` tags already on the page.
77+
You can convince yourself by checking the `length` property of `headers`:
78+
79+
<javascript caption="Viewing the number of 'h1' tags on the page">
80+
var allHeaders = $("h1");
81+
alert( allHeaders.length );
82+
</javascript>
83+
84+
If the page has more than one `<h1>` tag, this number will be greater than one.
85+
Likewise, if the page has no `<h1>` tags, the `length` property will be zero.
86+
Checking the `length` property is a common way to ensure that the selector described something on the page.
87+
88+
To make sure we only have the first header element, we have to take one more step.
89+
There are a number of ways to accomplish that, the most straight-forward may be the `eq()` function.
90+
91+
<javascript caption="Selecting only the first 'h1' element on the page (in a jQuery object)">
92+
var headers = $("h1");
93+
var firstHeader = headers.eq(0);
94+
</javascript>
95+
96+
Now we can be assured that `firstHeader` is a jQuery object containing only the first `<h1>` element on the page.
97+
And because `firstHeader` is a jQuery object, you can use methods like `html()` or `after()`.
98+
jQuery also has a method named `get()` which provides a related function.
99+
Instead of returning a jQuery-wrapped DOM element, it returns the DOM element itself.
100+
101+
<javascript caption="Selecting only the first 'h1' element on the page">
102+
var firstHeaderElem = $("h1").get(0);
103+
</javascript>
104+
105+
You can also treat the jQuery object like a true JavaScript array and use brackets to retrieve the DOM element you want, like so:
106+
107+
<javascript caption="Selecting only the first 'h1' element on the page (alternate approach)">
108+
var firstHeaderElem = $("h1")[0];
109+
</javascript>
110+
111+
In either case, `firstHeaderElem` contains the "native" DOM element.
112+
This means it has DOM properties like `innerHTML` and methods like `appendChild()`, but *not* jQuery methods like `html()` or `after()`.
113+
As discussed earlier, the element is more difficult to work with, but there are certain instances where you will need it.
114+
One such instance is making comparisons.
115+
116+
### Not all jQuery objects are created `===`
117+
118+
An important detail regarding this "wrapping" behavior is that each wrapped object is unique.
119+
This is true *even if the object was created with the same selector*.
120+
121+
<javascript caption="Creating two jQuery objects for the same element">
122+
var logo1 = $("#logo");
123+
var logo2 = $("#logo");
124+
</javascript>
125+
126+
Although `logo1` and `logo2` are created in the same way (and wrap the same DOM element), they are not the same object.
127+
For example:
128+
129+
<javascript caption="Comparing jQuery object">
130+
alert( $("#logo") === $("#logo") ); // alerts 'false'
131+
</javascript>
132+
133+
However, both objects contain the same DOM element.
134+
The `get` method is useful for testing if two jQuery objects have the same DOM element.
135+
136+
<javascript caption="Comparing DOM elements">
137+
var logo1 = $("$logo");
138+
var logo1Elem = logo1.get(0);
139+
140+
var logo2 = $("#logo");
141+
var logo2Elem = logo2.get(0);
142+
143+
alert( logo1Elem === logo2Elem ); // alerts 'true'
144+
</javascript>
145+
146+
Many developers prefix a `$` to the name of variables that contain jQuery objects in order to help differentiate.
147+
There is nothing magic about this practice--it just helps some people to keep track of what different variables contain.
148+
We could re-write the previous example to follow this convention:
149+
150+
<javascript caption="Comparing DOM elements (with more readable variable names)">
151+
var $logo1 = $("$logo");
152+
var logo1 = $logo1.get(0);
153+
154+
var $logo2 = $("#logo");
155+
var logo2 = $logo2.get(0);
156+
157+
alert( logo1 === logo2 ); // alerts 'true'
158+
</javascript>
159+
160+
This code functions identically to the example above, but it is a little more clear to read.
161+
162+
### jQuery objects are not "live"
163+
164+
Given a jQuery object with all the paragraph elements on the page:
165+
166+
<javascript caption="Selecting all 'p' elements on the page">
167+
var allParagraphs = $("p");
168+
</javascript>
169+
170+
...you might expect that the contents will grow and shrink over time as `<p>` elements are added and removed from the document.
171+
This is *not* actually the case.
172+
The set of elements contained within a jQuery object will not change unless you modify it in your code.
173+
This means that the collection is not "live"--it does not automatically update as the document changes.
174+
If you expect the document may have changed from when you created the jQuery object, then update your collection by creating a new one!
175+
It can be as easy as re-running the same selector:
176+
177+
<javascript caption="Updating the selection">
178+
allParagraphs = $("p");
179+
</javascript>
180+
181+
### Wrapping up
182+
183+
Although DOM elements provide all the functionality one needs to create interactive web pages, they can be a hassle to work with.
184+
The jQuery object wraps these elements to smooth out this experience and make common tasks easy.
185+
When creating or selecting elements with jQuery, the result will always be wrapped in a new jQuery object.
186+
If you do need the native DOM elements, you can always use the `get()` method and/or array-style subscripting to get at them.
187+
188+
These dinstinctions may not be immediately obvious, but understanding them is an important step in fully utilizing jQuery as it was intended.

0 commit comments

Comments
 (0)