Powerful jQuery with LiveScript

31 Jul 2012 - George Zahariev

jQuery is a very useful and powerful library. Unfortunately, its power is sometimes dampened by JavaScript's awkward syntax.

LiveScript is a language that compiles to JavaScript. It's just JavaScript with some syntax improvements and feature additions, allowing you to use jQuery to its full potential.

Are you familiar with CoffeeScript or LiveScript? If so you can skip ahead.

But first, we'll briefly go over the basics of LiveScript:

A Brief Overview of LiveScript

Like many modern languages, blocks are delimited by whitespace indentation and newlines are used instead of semicolons to terminate statements (you can still use semicolons if you want to fit more than one statement on a line).

For example (LiveScript on the left, compiled JavaScript on the right):

if 2 + 2 == 4
  doSomething()
if (2 + 2 === 4) {
  doSomething();
}

You can try all these examples for yourself using the LiveScript compiler/repl on the LiveScript site.

To further clear things up, you can omit the parentheses when calling a function.

add 2, 3
add(2, 3);

And comments are:

# from here to the end of the line.
// from here to the end of the line.

Defining functions, which we do often in jQuery for callbacks, can be cumbersome in JavaScript. You have to use an eight letter keyword function, and have to use all those curly braces and semicolons.

Things become a quite a bit lighter in LiveScript:


(x, y) -> x + y

-> # an empty function

times = (x, y) ->
  x * y
# multiple lines, and be assigned to a var like in JavaScript
var times;
(function(x, y){ return x + y; });

(function(){});

times = function(x, y){
  return x * y;
};

As you see, function definitions are considerably shorter! You may also have noticed that we have omitted return. In LiveScript, almost everything is an expression and the last one reached is automatically returned. However, you can still use return to force returns if you want, and you can add a bang to your definitions to suppress auto-returning noRet = !(x) -> ....

Chaining

jQuery is all about chaining. LiveScript makes chaining beautiful.

Spaced property access closes implicit calls, so you can omit a lot of parentheses. Furthermore, you can use a backslash to denote a single word string.

$ \h1 .find \img .prop \src
$('h1').find('img').prop('src');

You can call functions with no arguments with a bang !, eg. f!. When you do this and you are chaining you don't need to follow it up with a dot.

$ \.footer .parent!empty!append content

$ \.article .next!contents!
$('.footer').parent().empty().append(content);

$('.article').next().contents();

Cascading takes chaining a level further. No more annoying ends().


$ \.content .parent!
  ..find \.sidebar
    ..append newContent
    ..addClass \highlight
  ..toggleClass \dark
  ..prepend newHeader
var x$, y$;
x$ = $('.content').parent();
y$ = x$.find('.sidebar');
y$.append(newContent);
y$.addClass('highlight');
x$.toggleClass('dark');
x$.prepend(newHeader);

Backcalls

Backcalls allow you to unnest callback functions. They are like functions, except with the arrow pointing backwards.

First, a common example - annoyed that you have to indent everything because you are waiting for $(document).ready?

<-! $
initializeApp!
...
$(function(){
  initializeApp();
  ...
});

Backcalls really shine with Ajax.

data <-! $.get 'ajaxtest'
$ \.result .html data
processed <-! $.get 'ajaxprocess', data
$ \.result .append processed
$.get('ajaxtest', function(data){
  $('.result').html(data);
  $.get('ajaxprocess', data, function(processed){
    $('.result').append(processed);
  });
});

Iteration

List comprehensions provide a powerful way to iterate through collections.

values = [input.val! for form in $ \form for input in form]
var res$, i$, ref$, len$, form, j$, len1$, input, values;
res$ = [];
for(i$=0, len$=(ref$ = $('form')).length; i$ < len$; ++i$){
  form = ref$[i$];
  for (j$ = 0, len1$ = form.length; j$ < len1$; ++j$) {
    input = form[j$];
    res$.push(input.val());
  }
}
values = res$;

Conclusion

This has been a brief overview of just some of the features available in LiveScript. As you have seen, it provides a rich set of features which expose jQuery's full power.

For more information check out the LiveScript site


For more on LiveScript and prelude.ls, .

comments powered by Disqus