deviant art

Deviant Login Shop  Join deviantART for FREE Take the Tour
Group Info Group Founded 11 Years ago Statistics 38 Members
297,760 Pageviews824 Watchers

Upgrading to jQuery 1.9

Sat May 4, 2013, 11:20 PM

One of the most time consuming tasks involved with running a large website can be upgrading libraries. Of course we do this all the time, but sometimes those libraries are used across the entire site. One of those libraries that we use at deviantART is jQuery. Unfortunately, we got a little bit behind with keeping jQuery up to date and we were still on version 1.7. But over the last couple of months, #dt has upgraded the whole deviantART network to jQuery 1.9. As you may already know, this upgrade can be slightly challenging due to the number of changes that break backwards compatibility.


The first thing that everyone attempting to upgrade from an earlier version should use is the new jQuery.migrate plugin. This plugin is bundled with jQuery 1.9 and will generate console warnings when deprecated features are used. Without a doubt, this is the most helpful tool available for finding parts of your site that could break. To use the plugin, first include jQuery, then include the migrate plugin:


<script src="/styles/js/jquery.js">
<script src="/styles/js/jquery.migrate.js">

Also make sure that you enable warnings and traces, so that you can gather as much debugging information as possible. To do so, add this immediately after migrate.js:


jQuery.migrateMute = false;
jQuery.migrateTrace = true;

One of the significant changes in jQuery 1.9 is the removal of .live() and .die(), which have been superseded by .on() and .off(). Last summer, during our yearly summit, these calls were almost entirely removed from our JS. The last couple of live/die calls have now been completely removed.


Another significant issue that had to be resolved was the removal of .data('events'). Although very little of our JavaScript actually used this feature, not addressing it would have caused some serious issues. Resolving this was pretty straight forward and just required maintaining our own cache of attached events when necessary.


There were a couple of other small issues, but one of them was extremely important and it isn't terribly well explained in the migration guide: separating .prop() from .attr(). Simply put, .attr() is for changing HTML markup and .prop() is for changing the properties of a JavaScript object. Without jQuery, you would use element.setAttribute() to change the attributes of an element. Properties would be changed by directly assigning a value to them: element.checked, element.className, etc.


Sometimes the HTML markup and the element properties mirror each other, and sometimes they don't. Here are some examples:


An input element without a type attribute is actually a "text" input:


var $node = $('<input>');
$node.attr('type'); // undefined
$node.prop('type'); // "text"

The "checked" attribute of an checkbox only reflects the default state, not the active state:


var node = $('<input type="checkbox" checked="checked">').get(0);
node.checked = false;
node.getAttribute('checked'); // "checked", even though the checkbox was ticked off

The "value" attribute of an input only reflects the default state, not active state:


var node = $('<input type="text" value="foo">').get(0);
// assuming the value changed to "rubber duck" (by typing into the input) before code is run...
node.value; // "rubber duck"
node.outerHTML; // <input type="text" value="foo">
$(node).parent().html() // same as above, even with jQuery
node.getAttribute('value'); // "foo"

Note that jQuery does consider the value of some properties when using .html(), see this example.


The "href" attribute of a relative link does not represent the full link with protocol and domain:


var $node = $('<a href="/test>Test</a>');
$node.attr('href'); // "/test"
$node.prop('href'); // "http://www.deviantart.com/test"

The "selectedIndex" property of a dropdown tells you the currently selected option index:


var $node = $('<select><option>0</option><option>1</option><option selected>2</option>');
$node.attr('selectedIndex'); // undefined
$node.prop('selectedIndex'); // 2

As you can see, there is a very real difference between .attr() and .prop(). For a long time jQuery has been munging the returns of .attr() to reflect property values. Inevitably, this leads to confusion or outright broken code. Although this split is probably one of the most difficult changes to make correctly, we fully support the decision that jQuery has made.


So, in conclusion, what is the best way to use .attr() and .prop()? This is our recommendation:


// Bad
if (cond) {
   $(node).attr('checked', true);
} else {
   $(node).removeAttr('checked');
}
// Better
$(node).prop('checked', cond);
// Best
node.checked = cond;

#dt hopes that this post will help you with your upgrade to jQuery 1.9 and beyond!



More Journal Entries

Group Info

Group
Founded 11 Years ago
Oct 25, 2001

Location
Global

Group Focus
deviantART Related

38 Members
824 Watchers
297,760 Pageviews
Daily Pageviews

Sync

When DT finishes making a brand new deviantART feature, or just fixes a bug, we first run it on our top-secret staging server. When everything's ready to go live, we sync it!
Syncs Per Day

Group Twitter

Comments


Add a Comment:
 
:iconlablayers:
=LabLayers 1 day ago  Student Interface Designer
Congrats, you've outdone yourselves. [link]
Reply
:icon20after4:
`20after4 1 day ago  Hobbyist Photographer
I miss you guys :(
deviantART muro drawing Comment Drawing
Reply
:iconiioreostephanie:
=iiOreoStephanie May 30, 2013  Student Artist
Hello, im quite having trouble when i visit a group; [sometimes] this appears: [link]
but then, also in my message centre when i take a look it looks like this: [link]
Reply
:iconshadowhand:
$shadowhand May 30, 2013  Professional Artist
#dt doesn't handle user support, you should contact the help desk: [link]
Reply
Hidden by Owner
:iconblackwolfninja89:
hi there, i had a question in regards to the message centre. Is there a way to make it display again?
Reply
:iconfallencryingdevil:
Mood: Optimism ~FallenCryingDevil Mar 31, 2013  Hobbyist Artist
Hey, Developers! What about new emoticons? Who is involved?
Reply
:iconnever-ending-donkey:
Something very annoying seems to be up with the edit feature, at least in the "favorites" gallery. I was trying to drag some images around, but instead of registering this as editing, the site assumes I'm trying to favorite the images. I've tried refreshing the page, and going to other pages within my favorites, but the same thing keeps happening. The only time this doesn't happen is when I move an image at the very end of a favorites page to the next one. What's going on?
Reply
:iconchaojeffrey:
I wanted to Ask this Question, What Features are using HTML5?

I want to know the question about what features HTML5 is using seems to be not disclosed with the Tech Staff and Owner of the site
Reply
:iconbanks:
Hi,

Well I don't know if we made a definite list anywhere but to the best of my knowledge, main features we use widely right now are CSS3 (which is kinda a feature of HTML5 depending on your viewpoint), data-* attributes, muro obviously makes heavy use of Canvas, our video player uses HTML5 video playback, we use window.postMessage for cross-domain frame communication and I believe a few features have used localStorage API.

Hope that gives you some idea.
Reply
Add a Comment: