July 28th, 2010
Here are some of the more weird things I’ve found over the years when using JavaScript.
My most favorite quirk ever is:
typeof NaN
// => number
Recently, I stumbled upon the “magic increasing number”:
9999999999999999
// => 10000000000000000
And this is from my article on number parsing:
parseInt("01") // --> 1
parseInt("02") // --> 2
parseInt("07") // --> 7
parseInt("08") // --> 0
parseInt("09") // --> 0
There’s an extensive collection of these and more at wtfjs, so go check it out! Some are pretty obvious in hindsight, but some are really, really obscure.
If you think you know everything about JavaScript, you probably don’t… What’s your favorite JavaScript quirk?
July 26th, 2010

Want to learn how to build mobile web apps that use advanced CSS features like gradients and transformations, and HTML5 features like canvas, touch, audio, 2D and 3D animations, and more? Like you’ve seen on http://everytimezone.com and even more extreme?
Don’t panic! Amy and I proudly present: HTML5 Mobile Pro Workshop, a half-day online workshop on September 20, 2010, on building really great mobile HTML5 apps. We’ve limited the workshop to 25 virtual seats—so hurry if you want to join (we’ve sold a quarter of the seats already!).
Topics include: iOS (iPhone & iPad), Android and Palm WebOS Webkit-based browsers, capabilities of HTML5 & CSS3 & making them work for you, touch interfaces, hardware acceleration & 3D CSS, audio and video, fast loading, cross-browser issues and what works where, going offline and last but not least making it all AWESOME.
I personally want to see more awesome HTML5 apps out there, and the stuff you can do in mobile browsers is pretty mind-blowing (if you know how to implement it!), so join in on the fun!
July 21st, 2010
That is, at least for Webkit-based browsers that support the -webkit-animation CSS property.
@-webkit-keyframes blink {
0% { opacity: 0 } 50% { opacity: 0 }
50.01% { opacity: 1 } 100% { opacity: 1 }
}
blink {
-webkit-animation: blink 0.7s infinite linear alternate;
-webkit-font-smoothing: antialiased;
}
Why use -webkit-font-smoothing: antialiased, you ask? This forces the browser to never use sub-pixel antialiasing, which causes a visible “jump” when turning from <1 opacity to opacity=1. That way, the browser only uses normal antialiasing (this only matters for desktop browsers, mobile browsers use just plain old antialiasing by default).*
Full MIT-licensed source code is available on Github.
Want to learn how to do stuff like this (well, maybe not this exact thing)? Join my HTML5 Mobile Pro Workshop, a half-day online workshop on doing awesome mobile HTML5 sites and apps, exploring all the technologies that are available to you!
*Thanks to rkh for pointing out -webkit-font-smoothing.
July 15th, 2010
The good folks at Webstock (the most awesomest web conference there is!) have put up this years’ talk videos, so without further ado, here’s my talk where I can’t believe it’s not Flash*

Here’s my earlier article with the slides (view online and/or download).
In a cruel twist of fate, you can watch the video (or view the slides) only with Flash installed.
Note! The video is slow to load, because it’s streaming to you from New Zealand, a land well known for friendly people, beautiful, awe-inspiring nature, the good life, and horribly slow international internet connections. Give it some time!
*Actually, I can! That line is referring to one enthusiastic email that I received way back in 2005 when I first released script.aculo.us.
June 30th, 2010
Head over to http://scripty2.com/accel/ to see the teaser, and be sure to try it on an iPad or iPhone! 🙂
(To see the hardware acceleration in action you need to use a recent version of Safari, desktop or mobile).
Scripty2 is coming this summer as a beta release, and will include: super-user-friendly APIs, hardware-accelerated effects (without you having to know about all those -webkit-something-something properties), completely new and awesome, themeable and extensible user interface components, amazing interactive documentation, multi-touch support and much more.
Big thanks to Andrew Dupont for the hard work of making this work so flawlessly, and contributing tons of code to Scripty2!
Stay tuned!
June 29th, 2010
It’s summer and now is the best time to level up to JavaScript Ninja with one of Amy Hoy‘s and mine Virtual JavaScript Master Classes.
Here’s what our newly trained ninjas said about our first JavaScript Master Class that we did in June:
- “JavaScript Master Class worth every cent. Tons of docs, answers, insights, fun & encouragement. Highly recommended, super friendly.”
- “Enjoyed it, learnt a lot and the online format worked very well.”
- “Help & clarifications on the side [in the chat] = AWESOME team”
- “Completely Impressed”
We have not one, but TWO Master Classes lined up in July, both are two half-days so you get to breathe (and maybe do some of the homework!) between the parts. Both the classes are in US-friendly time zones (one is optimal for ET, the other one for PT).
All you need is a browser with Flash installed (I know, I know!), and we’re streaming live to you and you can interactively question everything and ask for more information on just about anything about JavaScript (we know a lot!).
Head over to our JavaScript Master Class site to learn more and sign up (right now, we still have early bird pricing on both classes, but not for long– you save a cool $70 with the early bird pricing!).
June 4th, 2010

About a month ago or so, Amy and I release a little (literally, it’s about 5k) HTML5 iPad App for looking up time zones. I don’t mean select-box wasteland like all other time zone sites (who likes select boxes anyway?!), I mean a nicely polished, touch-enabled UI that works offline, too.
The site uses no images (‘cept for the ad), no JavaScript framworks, and no external CSS, and fits quite comfortably in a few k’s of gzipped HTML.
First visit the site on your iPad (desktop browsers work, too!), and play around with it a bit.
Our first attempt ran really great on the Apple-supplied SDK iPad Simulator. But when we got our real iPads, everything seemed slow and sluggish. We went in an optimized the perceived “snappyness” when dragging the the time bar with your finger, and about doubled the rate of frames per second rendered.
And here’s what we did:
1. Images slow things down immensely– get rid of them
At first, we used a quite complex -webkit-gradient for the gradients in the “day bars” for the various cities. It turns out the this really, really slows things down in terms of rendering speed on the iPad. What -webkit-gradient really does is construct an image bitmap, and to the rendering engine it’s exactly the same as if you would supply and externally loaded image (like a PNG file). Images on Mobile Safari are notoriously slow (hope this will improve in 4.0!), and there’s basically nothing you can do about this– except not using images and gradients.
We replaced those bars with a big canvas element that sits in the background, and we redraw only those portions of the screen that undergoes changes (the different highlighting when you drag around the green bar). You can sort-of reuse -webkit-gradient when using canvas, like this:
// WebKit CSS gradient
-webkit-gradient(linear, left top, right top,
from(#4b4c4d),
color-stop(0.249, #4b4c4d),
color-stop(0.25, #575b5c),
color-stop(0.329, #575b5c),
color-stop(0.33, #6b7071),
color-stop(0.749, #6b7071),
color-stop(0.75, #575b5c),
color-stop(0.909, #575b5c),
color-stop(0.91, #4b4c4d),
to(#4b4c4d)
);
// <canvas> gradient
var gradient = $('canvas').getContext("2d").createLinearGradient(0,0,230,0);
gradient.addColorStop(0,'#4b4c4d');
gradient.addColorStop(0.249,'#4b4c4d');
gradient.addColorStop(0.25,'#575b5c');
gradient.addColorStop(0.329,'#575b5c');
gradient.addColorStop(0.33,'#6b7071');
gradient.addColorStop(0.749,'#6b7071');
gradient.addColorStop(0.75,'#575b5c');
gradient.addColorStop(0.909,'#575b5c');
gradient.addColorStop(0.91,'#4b4c4d');
gradient.addColorStop(1,'#4b4c4d');
2. Avoid text-shadow & box-shadow
Also a major source of slowdown. It’s best to avoid those CSS properties.
3. Hardware-acceleration is quite new… and buggy
On Safari, all you need to enable hardware-acceleration is to use the -webkit-transform CSS property (opacity also works, but see above).
There are limits to what works with hardware-acceleration, for example the number of concurrent animations is limited– there will be flickering and rendering errors if you have more then a handful of animations going on. Gently used, it makes things awesome however (can’t wait to share the new scripty2 hw-accel demos, coming next week I hope!).
4. Use touch events whenever you can
Touch events are great, because regular old onclick events only happen with a slight delay on the iPad. Opt for touch event instead– look into the source of the page for some hints on how you can provide support for non-touch-enabled browsers at the same time:
var supportsTouch = 'createTouch' in document;
element[supportsTouch ? 'ontouchmove' : 'onmousemove'] = function(event){
var pageX = event.pageX;
if (event.touches) pageX = event.touches[0].pageX;
// ...
}
5. Avoid opacity
For some reason, using the opacity CSS property sometimes interferes with hardware-accelerated rendering, so if you experience slowdowns and think you’re doing everything right, see if you have opacity set somewhere.
6. There is no silver bullet– hand-code JavaScript and CSS
Don’t rely on frameworks or what standards zealots tell you. In our case, a highly trimmed HTML page, with inline CSS, just some pure JavaScript without a framework and using the capabilities of the target platform (iPad) as much as possible allows for a lean page that loads almost instantly, caches well and works great offline. Yes, we could have used JavaScript and CSS frameworks, but sometimes less is more (and remember, you don’t need all the cross-browser heavy lifting that frameworks do for you).
// mini-pico-tiny convenience micro-framework, ymmv
function $(id){ return document.getElementById(id); }
function html(id, html){ $(id).innerHTML = html; }
function css(id, style){ $(id).style.cssText += ';'+style; }
function anim(id, transform, opacity, dur){
css(id, '-webkit-transition:-webkit-transform'+
',opacity '+(dur||0.5)+'s,'+(dur||0.5)+'s;-webkit-transform:'+
transform+';opacity:'+(1||opacity));
}
7. Use translate3d, not translate
When using -webkit-transform, be sure to use the translate3d(x,y,z) syntax, instead of using translate(x,y). For some reason, the latter is not hard-accelerated, at least not on iPhone OS 3.x (it seems to work fine on desktop Safari, tho). Thanks to Matteo Spinelli for pointing this out (check out his iScroll project for some a great code that demonstrates how to optimize performance on mobile WebKit)!
I think it’s quite exciting to develop apps with HTML5 on these devices, with almost complete desktop-like performance in most cases, and you can even distribute apps yourself, no need to go through the App Store for this.
I’d love to hear about your experiences, and quirks and tricks you may have come across.
Want to learn how to build your own AWESOME mobile HTML5 apps? Amy and I proudly present: HTML5 Mobile Pro Workshop, a half-day online workshop on September 20, 2010, on building really great mobile HTML5 apps. We’ve limited the workshop to 25 virtual seats—so hurry if you want to join!
May 28th, 2010
1 + + 1 // => 2
1 + - + 1 // => 0
1 + - + - + 1 // => 2
1 + - + - + - + 1 // => 0
1 + - + + + - + 1 // => 2
1 + / + + + / + 1 // => 1/ + + + /1
Sure, but what about this?
1 + / + / + / + 1 // => ?
May 27th, 2010
This summer, why not brush up your JavaScript skills? Really know what this does? Or what a prototype chain is (and why you might need it)? And what about that delete operator… And how can JavaScript code be turned from a big mess into neat building blocks?
It’s time to take Amy Hoy‘s and my JavaScript Masterclass Virtual Edition on June 24, 10am to 5pm GMT (London) time (use our time zone tool to compare to your time zone!).
The class is online, so you can take it in in a relaxed atmosphere, like your home in your pajamas, following along as we introduce you to the real JavaScript, the language that sits there quietly hiding (and sometimes loudly complaining) behind your favorite framework.
We’re not discussing any framework specifics, but focus exclusively on the language JavaScript, so whether you use Prototype, jQuery, YUI, dojo, or server-side hotness like node.js, you’ll learn a lot.
You get full all-day interaction with Amy and me, and can ask questions and one-on-one answers, as we will have a chat room, exercises and “homework”. And of course, you get course materials in PDF/HTML/JS form beforehand.
Oh, and on top of all this you’ll also receive a free copy of our JavaScript performance ebook including the DOM Monster, our DOM performance tool, yum!
All this for the super-low, early-bird price of just €275,-*! As we offer just 25 seats, be sure to book fast, as we expect to sell out very quickly!
We also plan to have these online, interactive classes in other time zones, please let us know if you’re interested in that, and whether or not you’d like a full one-day course like this one, or two half-day courses better! Plus, we also plan to do online performance workshops, let us know too if you’re interested.
*excl. VAT, if you’re from outside the EU, or have a business in a EU member country you are VAT-exempt and we’ll refund the VAT, otherwise it’s 20% Austrian VAT
May 12th, 2010
So you want to parse strings and convert them into numbers? JavaScript has the straight-forward parseInt method for this, you say.
parseInt("1") // --> 1
But, sadly, and quite unexpectedly, it’s not that straight-forward. Consider:
parseInt("01") // --> 1
parseInt("02") // --> 2
parseInt("07") // --> 7
parseInt("08") // --> 0 WTF?
parseInt("09") // --> 0 WTF?
parseInt thinks the numbers that are preceded by a “0” are octal numbers (in the octal numeral system only the digits 0 to 7 are used).
There’s a nice way to work around this, and also some more hackish methods. First off, let’s have a look at the “proper” way of fixing this issue:
parseInt("07", 10) // --> 7
parseInt("08", 10) // --> 8
parseInt("09", 10) // --> 9
The second argument to parseInt is a Radix to be used for the conversion of the string into a number. A radix of 10 means, use the decimal numeral system, which is probably what you want (the decimal system is also called “base ten”).
Some of you might strike this as quite verbose, and indeed, most other programming languages basically assume base 10, and let you specifically override the radix in case you really need to use that base 13 or base 7 numeral system. You can work around the verbosity and actually have a little bit of a performance optimization at the same time by coercing the string into a number, by applying an operator that requires numerical arguments.
Here is one way to make this shorter, and avoid the call to parseInt altogether:
// unary + operator
+"08" // -> 8
Though short and concise, the unary + operator might not always be a good choice, especially if you do calculations or string concatenation. You can use a double binary negation instead:
// unary + requires parenthesis
"test" + (+"08") // -> "test8"
// double binary negation
"test" + ~~"08" // -> "test8"
Be aware that while the unary + operator works with floating point numbers too, applying binary operators like the double negation will also cut off the fractional part of your number:
+"1.2" // -> 1.2
~~"1.2" // -> 1
~~"-1.2" // -> -1
// note: ~~ with negative numbers behaves differently from Math.floor
// Math.floor(-1.2) // -> -2
This can be used if you quickly want to convert a number that’s provided in a string and also cut off the fractional part (equivalent to rounding down for positive numbers).
If you need to optimize iterative algorithms, these optimizations can really help bringing down code size and as a side effect avoid expensive function calls (but please never ever optimize without a reason!).