deviant art

Deviant Login Shop  Join deviantART for FREE Take the Tour
Group Info Group Founded 11 Years ago Statistics 38 Members
297,733 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,733 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:
 
:icondanmilward:
Hey chaps. We sooo totally want the ability to upload things to sta.sh and open them in Muro. Can I talk to somebody on Skype about this?
Reply
:icon20after4:
`20after4 Nov 21, 2012  Hobbyist Photographer
That should be possible already...if not it'll be released soon.
Reply
:icondanmilward:
Thanks. We can't find any documentation about it if it is released :P
Reply
:iconclearfog:
!ClearFog Oct 28, 2012  Hobbyist Digital Artist
Your team Rules!
Reply
:icondanmilward:
Also I can't seem to access images in my stash from within muro... I'm not sure if that is a known bug or whether I'm just doing something totally wrong :P
Reply
:icondanmilward:
@pachunka hey mate - I was just wondering if we can connect and chat about how gamefroot.com and deviantART Muro might be able to work together. You mentioned connecting on Skype and I'm keen to have that conversation with you :)

Ciao,
Dan
Reply
:iconnever-ending-donkey:
There seems to be something wrong with the picture viewer on several new deviations. The thumbnails show up just fine, but the pictures don't load. Sometimes full view does load, but it takes forever. Could this be some temporary bug caused by the new layout?
Reply
:iconnamenotrequired:
^namenotrequired Oct 15, 2012  Student Interface Designer
The staff made an update about it in the Status Forum, see [link] :)
Reply
Add a Comment: