permalink

23

jQuery 1.7 Beta Release Preview

Hey guys. jQuery 1.7 Beta 1 just got released and I thought it would be interesting to give you a run-down of some of the main features that landed.

Introduction

Long-time jQuery contributors Dave, Rick, Corey, Jon Neal, Timmy and a handful of other enthusiastic developers have been hard at work this month landing a number of new features into jQuery core. The project has just wrapped up the first beta of version 1.7 which they're hoping to finalize in the next week or two.

Whilst patches and other commits are still being tested, I thought it would be interesting to take you through some of the new features you can expect to see in jQuery 1.7 through examples based on our unit tests – accompanied with explanations of what they have to offer and some extra comments.

All of these can be played around with using our up-to-the minute version of jQuery (git or 'edge' as it's called on jsFiddle.net) and should be cross-browser compatible.

Remember, if you happen to come across any quirks or bugs with these features, we'd appreciate it greatly if you could report bugs with them through our official bug tracker: http://bugs.jquery.com.

Support for registering jQuery as an Async/AMD Module

The first feature to land that I've been quite excited about has been support for registering jQuery as a CommonJS-compatible asynchronous module. This is something that wouldn't have been possible without the dedication of RequireJS author James Burke, who was responsible for much of the work that went into the commit.

There are a number of browser-based CommonJS-compatible script loaders (including RequireJS) which are capable of loading modules using an asynchronous module format. With this commit, jQuery now also registers itself using the format so it's able to take part in browser modules loading using any compatible loaders.

You may be curious as to why this is important.

Due to jQuery's popularity, AMD loaders need to take into account multiple versions of the library being loaded into the same page as you ideally don't want several different versions loading at the same time. Loaders have the option of either specifically taking this issue into account or instructing their users that there are known issues with their use and the library.

What James' addition brings to the table is that it helps avoid issues with other third party code on a page accidentally loading up a version of jQuery on the page that the page owner wasn't expecting. You don't want other instances clobbering your own and so this can be of benefit.

The way this works is that the script loader would indicate that it supports multiple jQuery versions by specifying that a property, define.amd.jQuery = true. For those interested in more specific implementation details, we register jQuery as a named module as there is a risk that it can be concatenated with other files which may use 'define', but not use a proper concat script that understands anonymous AMD module definitions.

The named AMD provides a safety blanket of being both robust and safe for most use-cases.

// Account for the existence of more than one global 
// instances of jQuery in the document, cater for testing 
// .noConflict()
var jQuery = this.jQuery || "jQuery", 
$ = this.$ || "$",
originaljQuery = jQuery,
original$ = $,
amdDefined;

// This is a mock AMD define function for testing AMD 
// registration, but could easily be replaced with one 
// of define variations from the wild. 
function define( name , dependencies, callback ){
	amdDefined = callback();
}

// The very easy to implement flag stating support which 
// would be used by the AMD loader
define.amd = {
	jQuery: true
};

//notice both instances are equivalent
console.log(jQuery, amdDefined); 
console.assert(jQuery==amdDefined);

Improved Support For HTML5 With jQuery

jQuery 1.7 won't come with it's own built-in HTML5 shivs (you'll still have to load in a shiv of choice into the document head), but it will address two important issues previous releases have suffered:

1) In jQuery 1.6.4 and below, HTML5 elements were not supported with innerHTML but this is rectified with the newest release. HTML5 elements now added with any methods using innerHTML under the hood are added to a successfully shim'd document or document fragment as one would expect.

2) HTML5 elements being cloned (when an element is cloneNode'd) will now use an alternative approach to cloning which supports cloning HTML5 elements cross browser.

// here's an example of a html5 shiv that would be loaded 
// in the head of your document you can of course alternative 
// between the solutions used for this

( "abbr article aside audio canvas details figcaption figure 
footer header hgroup " + "mark meter nav output progress section 
subline summary time video").replace(/\w+/g, function(n) {
	document.createElement(n);
});

// let's append some HTML5 elements which will be inserted 
// internally via innerHTML. This should now work fine with 
// all browsers, assuming a HTML5 shim/shiv is being used
$("#el").append("
"); // selection of HTML5 elements we added above var article = $("article"), aside = $("aside"); // simple tests to ensure that the HTML5 elements are valid // and can be styled via jQuery console.log( article.css("fontSize"), "15px", 'HTML5 elements can be styled'); console.log( aside.length, 1, 'HTML5 elements don't collapse their children')

Support for named queues that can be used by .animate()

In previous releases, .animate() supported queues – a feature which allowed a sequence of actions to be called on elements asynchronously without blocking application execution. In jQuery 1.7, Corey suggested adding support for queue names – a string which when supplied would queue animations based on queue names in a specific order. This is extremely useful for getting a more granular level of control over your animation sequencing.

Note how in the example below, each queue can be assigned a string representing an identifier (i.e the name). As confirmed by the 'order' array being updated, the order of callback execution experienced is preserved as desired because all queues are being defined under the same identifier.

// For this particular example, the first callback 
// function for the test is called via a setTimeout() 
// at the end just for the sake of demonstrating 
// dequeuing. You can of course just stick to queues 
// within your original animation chain for most common 
// needs.

// select an existing element for usage
var foo = $( "#foobar" ),
origWidth = foo.width(),
order = []; // here just for testing purposes

// animate with a named queue and some standard animation 
// properties
foo.animate( { width: origWidth + 100 }, {
	queue: 'name',
	duration: 1800,
	complete: function() {

	// our second callback function

	// push the order number into the stack so we 
	// test execution order was as expected
	order.push( 2 );
	console.log('second callback', order);

}
}).queue( "name", function( next ) {
	// last callback function
	console.log('last callback',order);
});

setTimeout( function() {
	// this is the first callback function that should 
	// be called
	order.push( 1 );
	console.log('first callback',order);

	foo.dequeue( "name" );
}, 100 );

Updated: Support For New Event APIs: .on() and .off()

In previous versions of jQuery, there were a number of ways to attach events to elements or remove them: .bind()/.unbind(),.delegate()/.undelegate() and .live(). Behind the scenes, because of the way these event APIs have evolved over time, a number of inconsistencies in their behaviour became apparent, some of which didn't entirely make clear how these events should be best used.

To help stabalize these APIs, we've introduced a new set of event APIs in jQuery 1.7 called .on() and .off(). As mentioned in the beta release post, the old event APIs are going to be staying for some time yet, but you may find using the new APIs more straight-forward:

// if a selector is supplied, we consider this a delegated event
// if not, it's considered directly bound
$(elem).on(events, selector, data, fn);

// similar to how you might use .unbind() or .undelegate(),  
// .off() simply 'unbinds' the events attached
$(elem).off(events, selector, fn);

For more information on this API, I recommend checking out the official beta release blog post for a useful table comparing how the behavior found in the old APIs correlates to the new ones.

Support for removing multiple attributes with .removeAttr()

Another minor, but interesting feature that was also added was the ability to remove multiple attributes from an element using .removeAttr(). Previously this method only allowed single attributes to be removed, but this has now been expanded to support space-separated attribute removal as demonstrated in the example below:

// create an element with a number of sample attributes we 
// can test
var div = $("<div id='a' alt='b' title='c' rel='d'></div>"),
tests = {
	id: "a",
	alt: "b",
	title: "c",
	rel: "d"
};

// check to make sure that all attributes have been 
// assigned correctly and exist with their expected 
// values
$.each( tests, function( key, val ) {
	console.log( div.attr(key), val, "Attribute `" + key + 
	"` exists, and has a value of `" + val + "`" );
});

// remove these attributes
div.removeAttr( "id alt title rel" );

// check to ensure these attributes are no longer present
$.each( tests, function( key, val ) {
	console.log( div.attr(key), undefined, "Attribute `" 
	+ key + "` was removed" );
});

Support disabling scanning the data cache for attributes multiple times

Quite a few developers use .data() in their projects for storing arbitrary data associated with an element. Beneath the hood, however, whenever you make more than a single call to .data(), you actually end up having to loop over all of the attributes for the element looking for 'data-' attributes each time you access it. With 1.7, we've introduced an optimization which avoids this, meaning that applications making heavy use of .data() will have to do just a little less work than previous versions.

// Here's a jsPerf performance test of the optimizations 
// thanks to Corey http://jsperf.com/internal-data/3

var testing = {
test: "testing",
test2: "testing"
},

element = jQuery( "<div data-test='testing'>" ),
node = element[ 0 ];

// assign some data-attributes to our node for testing
node.setAttribute( "data-test2", "testing" );

// ensure that the data we've set is actually present - 
// minor sanity check
console.log( element.data(), testing, "Sanity Check" );

// assign some more data-attributes
node.setAttribute( "data-test3", "testing" );

// check if .data() has changed as the data-* attributes 
// have console.log( element.data(), testing, "The data 
// didn't change even though the data-* attrs did" );

// clean up data cache
element.remove();

Conclusions

That's it for this preview. I hope you enjoyed it. These features are only a fraction of what's landed so far for 1.7, but if you're interested in keeping up with changes as they get made, feel free to checkout jQuery on GitHub. We also have a twitter account that gets updated on each commit over at @jquerycommits for anyone that prefers that route.

Until next time, happy coding!.

23 Comments

  1. Pingback: jQuery: » jQuery 1.7 Beta 1 Released

  2. Pingback: Elegant D » jQuery 1.7 Beta Release Preview

  3. Hi Addy, great article. A clarification around the AMD. AMD has been discussed on the CommonJS list and was a draft specification but did not reach full consensus, so further development moved to the amdjs group. So it is best to just refer to the AMD work as AMD or Async Module support and not CommonJS AMD, since not all participants on the CommonJS list wanted to pursue it.

    Further info on the amdjs group on github: https://github.com/amdjs

    • Hey James,

      (Thank *you* for pushing to get that change into jQuery!). I appreciate the clarification on the current position of AMD with respect to CommonJS. I had assumed that it was still being referenced as a CommonJS project, but I'll be sure to update the post to reflect the correct naming asap.

      Thanks for stopping by.

      Addy

      • My personal hope is that we can approach CommonJS again now that AMD has gained such traction. The CommonJS folks need to face reality: JavaScript is everywhere, but especially in the browser. To ignore the needs of the browser community is just dumb.

        Awesome write-up, btw. Keep it up.

        – John

  4. Pingback: Lançado o jQuery 1.7 Beta 1 | Notícia | jQuery Brasil

  5. Pingback: jQuery 1.7 Beta 1 veröffentlicht « dennis-dorsch.de | Webdesign | Programmierung | News | Leipzig

  6. Pingback: TechnikLOAD 52 – Amazon Kindle Fire, Amazon Silk, Facebook Spartan und visuelle Leckerbissen | TechnikLOAD

  7. Thanks for the update. I'm always a little hesitant to new releases. I'll have to wait a bit to see all of the bugs. I learned my lesson after Vista.

  8. Pingback: Demystifying jQuery 1.7′s $.Callbacks

  9. A question about jQuery and AMD:
    I thought one of the purposes of the module pattern and AMD was to avoid pollution of global. With the release of jQuery 1.7, I was expecting jQuery to be no longer available in global, but it turns out that:
    * it still is
    * jQuery has yet to be loaded via a <script> tag for the AMD functionnality to work properly

    Is there something I didn't understand and/or do correctly ?

    • yeah. Perhaps because so many people are using it – so it's impossible to wrap jQuery into define function as this would force everyone into using AMD loaders. So pollution is still there.
      It probably be better to create alternative jQuery file that's packaged fully as AMD module. Another problem is – as of now define() in jQuery called prior to the file end, so not all functionality of jQuery will be loaded by that moment which will lead to errors. I think there is a bug report for this already. IMHO – jquery AMD implementation as of now is half-arsed.

      • Agree.

        I don't know that well the core of jQuery, but couldn't a workaround such as a jq.global() function (once jQuery is loaded with the name jq as an AMD module)
        provide the backward compatibility for all the existing code and plugins?

  10. Great post at jQuery 1.7 Beta Release Preview. I was checking continuously this blog and I’m impressed! Extremely helpful information specially the last part :) I care for such information a lot. I was looking for this certain information for a long time. Thank you and best of luck.

  11. Wow, awesome blog layout! How long have you been blogging for? you made blogging look easy. The overall look of your website is magnificent, as well as the content!. Thanks For Your article about jQuery 1.7 Beta Release Preview .

Leave a Reply

Required fields are marked *.