Recently on Beyond Standards
To carry on with Javascript, I’m going to talk about a little circular problem I ran into today while dynamically inserting elements into a page.
Let’s say you have a page with a list and you want to do something when someone clicks on the list items:
<ul id="taskList">
<li>first item</li>
<li>second item</li>
...
</ul>
Typically, with jQuery you would attach handlers to the list items like so:
$(document).ready(function(){
$('#taskList li').bind('click', function(){
doSomething();
});
});
So far so good, but suppose you want to insert a list under the element you click on? You will also need to attach handlers for the items you’ve inserted! Let’s see:
$(document).ready(function(){
$('#taskList li').bind('click', function(){
insertSublistUnder(this);
// now let's attach the new handlers
$(this).find('li').bind('click', function(){
insertSublistUnder(this);
// now let's attach the new handlers...
// hey, wait a minute !!!!
});
});
});
You see the pattern here, it could go on and on !!!
So how do you do this?
Short answer: if your version of jQuery is 1.3+, use live instead of bind to attach the handlers (this ensures that all <li> inserted in the future will have their handlers bound automatically:
$(document).ready(function(){
$('#taskList li').live('click', function(){
insertSublistUnder(this);
});
});
But what do you do if you’re stuck in pre-1.3 land ?
Let’s see, we are attaching handlers which in turn insert some items and… attach some handlers which…
We have a bit of recursion here:
$(document).ready(function(){ <------------------\
$('#taskList li').bind('click', function(){ |
insertSublistUnder(this); |
// here call this ------------------------/
// on the newly inserted items
});
});
Let’s pack the recursive snippet into a function, say, ‘ attachHandlersUnder’, which takes a (clicked) list element as a parameter:
function attachHandlersUnder(li){
$(li).find('li').bind('click', function(){
insertSublistUnder(this);
attachHandlersUnder(this); // recursive definition
});
}
$(document).ready(function(){
attachHandlersUnder('#taskList'); //
});
Et voila !
Well, in essence… It is actually a bit more complicated, since calling ‘bind’ repeatedly on an element keeps adding handlers to the ones previously set.
Here’s a file with the final code.
This post talks about Javascript and the unfortunate combination of two quirks which can cause a few surprises.
Quirk 1: + as addition and concatenation
Javascript, unlike other languages use the same symbol for number addition and string concatenation:
1 + 1 => 2
'1' + '1' => '11'
Quirk 2: implicit type conversion
Javascript does not always throw an error when evaluating expressions with an odd mix of values and operators, such as, ‘10′ / ‘5′, instead it tries to converts values behind the scene (yes, you should be scared). Usually strings involved in arithmetic operations are converted to number, so :
'10' / 5 => 10 / 5 => 2
So it seems safe to assume that string representation of numbers will be treated as numbers in arithmetic operations, right ? Not so if the + operator is involved! Remember:
'1' + '1' => '11'
Form and formula
Suppose we have a form that asks for two numbers, and some Javascript which calculates the average. Let’s say the user types ‘1′ and ‘1′:
// Form values are strings
var number1 = $('#number1').val(); // '1'
var number2 = $('#number2').val(); // '1'
var average = (number1 + number2) / 2 ; // 5.5 !!
we get 5.5 instead of 1 because (number1 + number2) is concatenation and not addition.
The workaround in that case is to convert the form values to numbers beforehand :
var number1 = Number($('#number1').val()); // 1
var number2 = Number($('#number2').val()); // 1
var average = (number1 + number2) / 2 ; // 1
What makes this especially bad, is that the program appears to be working; it just silently returns the wrong result ! So remember, be cautious when using strings and addition in Javascript…

[Images via Gizmodo]
It appears that not only have Microsoft been poring over my posts here on Beyond Standards where Apple have failed to meet my meagre needs, Asus apear to have taken it a step further.
With a spanking new prototype on display at CES, the Asus Eee Keyboard PC looks like a brilliant idea.
Where I only asked for a stand-alone multi-touch trackpad, Asus have taken the concept one step further by cramming an entire ultra-portable PC into a keyboard with most of the industrial design queues of Cupertino’s finest.

With a built in touchscreen instead of the customary number pad you could have everything from a calendar to email and RSS widgets on there, instantly hot-swappable with a number pad or even bespoke gaming or multimedia control. Genius.
Now if they could just create a simpler version which is just a keyboard and trackpad so I can buy one for work and at least 2 for home I will be a happy man!
Way back in March I wrote a little missive imploring the good people of Cupertino to bring out a trackpad to replace the old-fashioned Microsoft mouse lurking just to the right of my decidedly svelte Apple keyboard, but it appears that it may be the Microsoft folks in Redmond who hit that particular milestone first.
Lets just hope that they make it look nice, feel nice, and work well… unlike Vista (sorry - I had to say it. We’ve got a Vista machine at home and I had to use it recently when the VPN to work stopped playing nice with my MacBook, and I just can’t use Windows any more - it makes me want to break things).
I know Apple have a chequered history when it comes to the humble pointing device (i.e. they’ve never really made a good one), but it just seems to be a no-brainer when they’ve already got the technology in place in the MacBook Pro line (and the iPhone), they’ve already got a simple aesthetic that it could fit into very nicely, and they’ve got an image-conscious target audience who would benefit from the interface options that it would present.
Surely I’m not the only one who thinks that a multi-touch trackpad would pretty much kick ass in place of the old-school mouse? Am I?
Bueller? Bueller? Bueller?..
Last year Steve Yegge speculated that Javascript (JS from now on) would become the Next Big Thing, that is, reach the level of ubiquity that only C, C++ or Java have so far experienced.
In August, the future of JS, Ecmascript-4, was buried only to be born again as ECMAScript-Harmony. It is a lot less complex and we should see the first implementations early next year.
Meanwhile, JS browser engines are out-speeding each other, bringing closer the day when JS will render and animate in your browser as smoothly as Flash or a Desktop application:
In June, Webkit, announced SquirrelFish, their next generation JS engine. It now compiles JS syntax tree to bytecode, making SquirrelFish 1.5 times faster than Firefox 3.
On Saturday, Mozilla announced that TraceMonkey, the next version of their JS engine, will be available in FF 3.1. It incorporates the Tracing Just-In-Time compiler Adobe developed for Actionscript and is roughly twice faster than FF3’s engine (6 times faster at manipulating images) !
Great ! But how does it work ? TraceMonkey finds hotspots, selected parts of the software where a lot of time is spent, based on the actual execution of the program. These hotspots are then compiled into native instructions the computer can understand. This selective compilation doesn’t require a lot of memory (unlike entire programs compilers), which means that it’s also good for mobile devices, one of Mozilla’s main focuses for browser development.
To get an idea of the speedup, here is a screencast showing image manipulations with FF3 and with FF3.1 (with TraceMonkey).
To try TraceMonkey, get a nightly of Firefox 3.1, open about:config, and set javascript.options.jit.content to true (it’s disabled by default).
Both SquirrelFish and TraceMonkey take advantage of cutting edge Programming Language research, and it’s just the beginning of JS implementation speed-ups, they say ! Microsoft has to step up its game !
Maybe Steve Yegge was onto something after all…
PS: Oh yes and Google just announced they are launching a new browser, Chrome, based on Webkit it will feature… V8, a new Javascript engine, meant to be faster and safer ! So there we are, Mozilla, Apple and now Google are raising the bar.