Coding with Jesse

Avoiding web page zoom in the iPhone and iPod Touch

I've been doing a bit of experimentation with web pages in the iPhone, and I've realised the first major problem is trying to prevent the iPhone from zooming way out on a web page, making it rather difficult to work with and more difficult to read.

One would assume that a 100%-width layout would be good enough for the iPhone's Safari to stop setting the browser width to 964px. But alas, it's not.

I had a look at probably the best iPhone app out there right now, Joe Hewitt's Facebook for the iPhone. Joe was awesome enough to release iUI, a collection of CSS, JavaScript and images for making user interfaces that match the look and feel of the iPhone.

I spent some time dissecting his examples, and eventually realised it wasn't the CSS nor the JavaScript which was able to stop the iPhone Safari from resizing. It was just a <meta> tag in the <head>:

<meta name="viewport" content="width=320; initial-scale=1.0; maximum-scale=1.0; user-scalable=0;"/>

It turns out this was all well documented on Apple's site, iPhone for Web Developers. There are lots of other techniques discussed like how to specify stylesheets and integrate with the built-in Google Maps application.

I hope that other device manufacturers implement things like the <meta name="viewport"> tag and the only-for-certain-widths stylesheets. The iPhone may not end up in everyone's pocket, but we will need to make web sites and applications that work across an ever-wider range of devices.

Published on September 7th, 2007. © Jesse Skinner

Private JavaScript Variables

I find myself needing to generate unique IDs in JavaScript a lot lately. Mostly this happens when I'm creating a lot of elements dynamically and I need to assign some unique ID to them so that I can find them later. And I need to do this because I've realised that storing pointers to elements in JavaScript uses a LOT more memory than just storing the ID of an element and finding it later with getElementById().

So anyway, what's a good way of generating unique IDs?

A simple way is to just keep a counter going and increment it every time you access it, like this:

var guid_counter = 0;

for (var i=0;i < 100;i++) {
    // create a new <div> element
    var div = document.createElement('div');

    // assign a unique ID and increment counter
    div.id = 'div_' + (guid_counter++);

    // append to the page
    document.body.appendChild(div);
}

With this you'll end up with 100 <div>s with IDs from "div_0" to "div_99". But our guid_counter is just sitting out there in the open! Someone could come along (like us making a typo) and write guid_counter = 0 or guid_counter-- and mess everything up! We could end up with 2 elements with the same ID!

We can improve on this by using a private variable. Private variables give us more control over global variables like our guid_counter, because we can choose when and how they are accessed and updated. Let's create a function which contains our guid counter as a private variable:

// 'guid' is assigned to the return value of this outer function
var guid = (function() {
    // same guid counter, but we keep it hidden inside here
    var guid_counter = 0;

    // return a function that has access to guid_counter
    return function() {
        // whenever guid() is called, return and increment the counter
        return guid_counter++;
    };

})(); // note the () - this executes the outer function right now!

If this is the first time you're seeing this syntax (or the hundredth) it can be a bit confusing. Really, we're doing the same thing as this:

function generate_guid_function() {
    // nothing outside of generate_guid_function() can access this
    var guid_counter = 0;

    // return a function that has access to guid_counter
    return function() {
        // return and increment the counter
        return guid_counter++;
    };
}

// 'guid' is assigned to return value of generate_guid_function()
var guid = generate_guid_function();

The magic of all this is in JavaScript Closures. The inner function has access to guid_counter because of where it's defined, but our code outside has no way to change or access guid_counter. This is exactly like private instance variables in Java and other languages.

Now, we can safely rely on our guid() function to generate unique IDs without worrying about our guid_counter being touched:

for (var i=0;i < 100;i++) {
    // create a new <div> element
    var div = document.createElement('div');

    // assign a unique ID from our new guid() function
    div.id = 'div_' + guid();

    // append to the page
    document.body.appendChild(div);
}
Published on August 26th, 2007. © Jesse Skinner

addDOMLoadEvent Revisited

I've gone back and reworked addDOMLoadEvent. I got rid of the global variables and reduced the size down to 563 bytes!

For the new script and the demo pages, check out addDOMLoadEvent.

Update [Aug. 19, 2007]: Now the script preserves any existing window.onload function, and also executes functions instantly when called after the page has already loaded. But now the compressed version is a hefty 617 bytes.

Published on August 14th, 2007. © Jesse Skinner

Unobtrusive Ajax

I wrote a Short Cut for O'Reilly that just came out called Unobtrusive Ajax. You can buy it online for just $9.99.

It's a 57-page PDF that goes into depth on using JavaScript and Ajax unobtrusively, an extension of my Unobtrusive Ajax presentation. From the description:

Unobtrusive Ajax is about making web applications that work for everyone all the time, even if you have JavaScript turned off, or you're using a mobile phone or a screen reader, or however you happen to be using the Web. It's about the separation of behavior (JavaScript), content (HTML), and presentation (CSS).

This short cut will focus on the practical benefits of using Ajax and JavaScript unobtrusively and show you that unobtrusive web development and progressive enhancement benefit both web developers and users of the Web. You'll get to see many simple examples of building web interfaces that are unobtrusive. You'll quickly see that it is actually very easy to make web applications that everyone can use.

When you're finished reading this short cut, you will be able to convince anyone why developing unobtrusively is the best way to build a site with JavaScript and Ajax.

I'd like to give a big thanks to the king of Unobtrusive JavaScript, Christian Heilmann, for giving me a great technical review.

If you're into this sort of thing, or even if you're not but wondering if you should be, I recommend you check it out.

Published on July 27th, 2007. © Jesse Skinner

Confusing JavaScript Equality

I got tripped up today by something that took me a few minutes to figure out. I wrote this:

if (a == b == 0) {
    // only execute if both a and b are zero
}

But this was wrong. In fact, you can write this:

alert(3 == 4 == 0); // alerts "true"

Why is that? Because of the order things are evaluated. I made the mistake of thinking == has the same result as doing =:

var x, y;

x = y = 10;

alert(x); // 10
alert(y); // 10

But when you use == like that, it actually compares the firsts two values, then compares the result (true or false) against the 3rd value. It's the same as writing:

alert(3 == 4 == 0); // true
alert((3 == 4) == 0); // true

because 3 == 4 is false, and false == 0 is true!

Published on July 25th, 2007. © Jesse Skinner
<< older posts newer posts >> All posts

Contact Jesse

Need help with a project? Any questions about my writing? I'd love to hear from you.

Email me at [email protected]