Wednesday, March 13, 2013

Exploring jQuery Queues

This week I ran into an interesting issue at work. There was an event that was triggered when a custom font loaded that added a fixed position element to an item in a container. Another team wrote some code that caused that container to animate when the page loaded. Sometimes the fixed position element would get placed randomly inside that container because the event was firing before the animation completed. Instead of tightly coupling the animation with the positioning of the element I decided to inspect the animating element's FX queue when the event was triggered to make sure that the element was not in the process of moving when it was added.
Queues in jQuery are a useful way to add a list functions to an element that should be executed in a particular order. The real benefit is that queues give you full control of when each item in the queue is invoked using the dequeue method. If you've used a jQuery animation function you've already used the jQuery fx queue. What a lot of people don't know is that jQuery provides a nice API for inspecting and manipulating queues.

Lets take a look at the typical use case for a jQuery queue; adding multiple animations to an element:



Demo:

JS Bin


When this code is executed each function is invoked one immediately right after the other. However, each animation is NOT performed instantly, each animation is added to the elements fx queue. When each animation is finished the next animation in the queue is invoked.

One interesting thing to note about the fx queue is that calling the stop() method on an element that is animating will only stop the current animation in the queue and immediately call the next animation in the queue. In order to truly stop all of the the animations the element's queue must be cleared as well.
In order to modify the first example to stop all animations when an element is clicked the following code is needed:



Demo:

JS Bin

Delaying And Creating Queues

Custom queues can be created on any elements by passing in a name to the queue call. In addition any queue's execution can be delayed when it is dequeued by using the delay( delayMs, queueName ) method. It's important to note that the delays are added to the queue itself so they need to be added to the queue before the function that you want delayed, however calling dequeue will trigger the delay and invoke the next callback from the queue. This timer will not start until dequeue() is called on the element's queue.

In the following example the queue's execution will be delayed by 1 second, an item will be added to the element, the queue will be delayed by another half second, another item will be appended to the element, the queue is then delayed for another second, and finally another item will be added to the element. The first item in the queue will be invoked in the $.ready() function and each callback in the queue will dequeue the next item in the queue.



Demo:

JS Bin

What makes custom queues with delays an attractive alternative to setTimeout or setInterval is that each item in the queue can have a different delay time before it is invoked.

Wednesday, February 27, 2013

Playing with ECMAScript.Harmony Modules using Traceur

As aI was a preparing a presentation on AMD and RequireJS I started looking ahead at the modules proposed for ECMAScript.Harmony.  In Addy Osmani's article Writing Modular JavaScript With AMD, CommonJS & ES Harmony he mentioned called Traceur which is a JavaScript compiler for ECMAScript Harmony syntax. This allows developers to give the future of JavaScript a test drive today.

One of the new features coming in Harmony that has me excited is modules. Modules will be a way to encapsulate code and explicitly define its dependencies and public API. ES Harmony gives us three new keywords for modules: module, import, and export. The module keyword is used to initialize a new module, the import keyword declares dependencies to import from a module into a context, and the export keyword explicitly declares public properties that will be available for other modules to import.

In addition Harmony modules:
  • are statically scoped
  • have the this keyword bound to the global object

Traceur

Before we are able to write modules today we'll need an environment that supports Harmony syntax. For this we'll use Google's Traceur compiler. In order to implement Traceur you'll need three things:
  1. Traceur library file
  2. Traceur bootstrap file
  3. Harmony code
Adding the Traceur library and bootstrap to an application is as easy as adding the scripts to a web page:



Now that we have a compiler in place we just need some code for it to compile. To do this simply create a script block with a type of script/traceur.



When the page loads Traceur will compile your Harmony code to JavaScript that works in today's modern browsers.

For your convince I've created a JS Bin with Traceur ready to go on JS Bin. In addition there is an online compiler you can use here: http://traceur-compiler.googlecode.com/git/demo/repl.html

Now that we have an environment that supports Harmony to work in lets take a look at modules.

Playing With Modules


First I'd like to point modules aren't meant to be classes, there the class keyword for that. According to the ECMAScript Wiki modules are a
"Standardized mechanism for creating libraries"
Modules do not create a new execution context, the this keyword in a module is bound to the global object. Looking at the code that Traceur outputs for a simple module definition shows this:



Even though a module does not get a new execution context , it does get a new static scope. In the following code I am creating a new module called carFactory that exports a variable named ford into the global namespace. Calling ford.wheels results in '4' and trying to access carFactory's internal wheels variable results in an error:

JS Bin

Its also important to note that doing an import * will import the variables from the modules with the same names the have in the module.

A module can also have multiple exports as shown in the following code (note the syntax for importing multiple exports in a single statement):

JS Bin

A module also doesn't only have to export objects, it can export anything:

JS Bin

Variables that are imported can also renamed the from modules using the following syntax:

JS Bin

Lastly modules can be nexted. Nested modules have privileged access to their parent modules scope. Nested modules are also private to their parent modules scope unless they are explicitly exported. Here is an example of a public nested module that accesses its parents scope:

JS Bin

Conclusion

Modules in Harmony look like they are going to be very useful and there's a lot you can do with them.  They help reduce the need for the overuse of the function keyword and reduce the need for patterns like AMD and complex loaders RequireJS and CurlJS (of which I am currently a huge fan).   For more reading on modules I suggest checking out the modules section on the ECMAScript Harmony WIKI.

Wednesday, October 24, 2012

jsonmé: A Simple HTML and JavaScript Resume Generator

It's been forever since I updated my resumé so I decided to turn my GitHub page into my living resumé.  Being a web developer I wanted to so something unique yet simple.  After playing around with a few concepts I decided to put all of my resume's data into a JSON file and create a small web app that would read it via AJAX and display its contents.  I was so happy with the result that I decided to extract out the code and put it up on GitHub and the result is jsonmé.

I wanted jsonmé to have a small footprint yet work in all browsers back to IE6.  I decided to use the Sizzle.js selector engine since it has such a proven track record in jQuery.  I also needed a small library for doing normalized AJAX requests.  I settled on snack.js, its a small and well written utility library with AJAX capabilities that also gives me a normalized document ready function.  

The resulting application is a simple and easy to implement application.  The easiest way to create your jsonmé is to fork the GitHub repository and rename it to .github.com.  For instance my personal resume is at http://bittersweetryan.github.com.  

The code is completely Open Source and licensed under the MIT license so feel free to grab it and do whatever you want with it.  If you do something awesome with it I'd love to hear about it or even get a pull request for it.

The source can be found at: https://github.com/bittersweetryan/jsonme

Thursday, October 4, 2012

Using the Partial Application Pattern in ColdFusion 10

The partial application pattern has been popular in JavaScript for some time now, Ben Alman has a great article on it: http://benalman.com/news/2012/09/partial-application-in-javascript/.   While refactoring some particularly redundant code I decided to try this pattern in ColdFusion using the power of closures and the function datatype.

The Partial Pattern


Lets start by taking one of Ben's examples and converting it to ColdFusion. Minuse a few syntactical changes we could almost copy and paste his code into ColdFusion. Lets start of by looking at a simple add function:

Now lets say we use that function to add one to a few numbers:

Instead of passing the parameter one to each function call wouldn't it be nice to have a function called addOne that just adds one to whatever argument is passed in? Simple. We can just create a new, more specialized, function that returns the invocation of our add function that always passes one as its first parameter:

Thats great. What if we want to add other numbers? We'd have to create a separate function for each number. What if those numbers aren't always known when we are writing our code, are we going to write a million different utility functions? Of course not. We can take the concept of creating a specialized function step further using the function datatype and closures to create a partial application that will help us construct new helper functions on the fly:

Looking at the code there are a few important concepts to note. First look at how this new function returns a function, this is a new datatype on ColdFusion 10 so this code will not work in any version less than 10. Second, and most importantly, look at how this new function is a closure. When we invoke the makeAdder function the inner function that is returned has access to makeAdder's argument even after makeAdder is invoked.

Since the makeAdder function returns a function we need to set a variable equal to the makeAdder's result to use it. Once we do that the new function can be invoked just like any other function:

Real World Example


In my application I had a function that took a long list of arguments which was called multiple times with only a few of the arguments changing between each call. This created some ugly code that was getting to be a pain to maintain. Instead of calling this function multiple times passing in all the arguments each time I decided to use the partial application pattern to clean up some of my code. This is what my new partial function looked like:
Instead of having one function that has 7 arguments that is called multiple times I have one function that takes 5 arguments that is called once. This function returns another function that gets called with only 3 arguments:

When ColdFusion first got closures I was unable to make the mental connection to how I was using closures in the JavaScript code I was writing. Slowly I am starting to write my ColdFusion more like I write JavaScript.




Wednesday, October 3, 2012

NCDevCon "The Art of JavaScript" Presentation Links

This is just a real quick post so I can share the link to my NCDevCon presentation slides and video.

The slides can be found at:

http://bittersweetryan.github.com/art-of-javascript/

The video can be found at (sorry, its in Silverlight format only):

http://textiles.online.ncsu.edu/online/SilverlightPlayer/Default.aspx?peid=02c7fe6174654f96b78a6194d3dbbe9d1d

One more thing, I was mentioned in the KeyNote!  You can watch that here, I'm mentioned in the second section about: "ColdFusion Today":

http://textiles.online.ncsu.edu/online/SilverlightPlayer/Default.aspx?peid=9c64b0db237e4240847875f95795138d1d

Please if you enjoyed let me know, or if you have any questions or suggestions how I can make this presentation better please let me know!
Fork me on GitHub