January 25th 2009
Google Reader
: The Onion: Apple announces Friend BarThe Unofficial Apple Weblog (TUAW)
Filed under: Humor

The Onion makes with the funny in this satirical video short about the "Apple Friend Bar," a new section of Apple Stores where Apple fans can go to discuss major issues at length, such as how much better Safari is than any other browser, or "what 'the Woz' has been up to." As usual, they pretty much hit the nail on the head for the stereotypical Apple fan -- I especially laughed at the improv troupe joke.
Stay tuned near the end for a joke about an in-home Apple Store -- at a cost of over $6000, it is fairly expensive, but then Apple products never are cheap. I'd love to have an Apple Store in my house right now, actually: maybe it would have an iPhone 4 in stock for me. You can watch the embedded video after the break.
TUAWThe Onion: Apple announces Friend Bar originally appeared on The Unofficial Apple Weblog (TUAW) on Thu, 08 Jul 2010 21:00:00 EST. Please see our terms for use of feeds.
: Spicing Up Your Website With jQuery GoodnessSmashing Magazine Feed
There comes a point in every website design when you simply want to give the website a little spice to impress the visitor and make it memorable. You want that sexy interaction to capture the user’s attention. In our previous articles, we showed you how to spice up your website with sexy buttons, practical elements and attractive visual effects.
In this article, we’ll discuss how to seduce your visitors with a little JavaScript action. In our examples, we’ll be using jQuery, a fast and concise JavaScript library that simplifies HTML document traversing, event handling, animation and Ajax interactions for rapid Web development. Ready? Let’s get things rolling!
[By the way, did you know we have a brand new free Smashing Email Newsletter? Subscribe now and get fresh short tips and tricks on Tuesdays!]
Ajax Image Uploader
Image uploads will be much better after your read this. Guaranteed. By using a bit of jQuery, we can upload images with previews.
How do you upload images now? You select a file and click upload. Simple, right? Except that once you select your image, you can no longer see what was selected. The name of the file is at the end of the input field, and if the input field is short or the file path is deep, you won’t see anything useful. You’ll forget what you selected and have no idea what you’re about to upload.
Now try this variation on uploading an image. We ditch the “Upload” button in favor of a “Save” button and fire the Ajax upload event as soon as a file is selected. The image is processed server-side, and a thumbnail is loaded onto the existing page. Doesn’t that feel so much better? We now have a visual representation (imagine that!) of the image we selected.
This is particularly useful in larger forms where many fields will be submitted in a single action. It allows the user to review the form before pressing “Save” and see what image (or images) they selected.
How does it work? Here’s the code. You’l need jQuery and the Ajax Upload jQuery plug-in. Link them up, and make sure jQuery is loaded first.
Here is the JavaScript we will use in its entirety.
$(document).ready(function(){
var thumb = $('img#thumb');
new AjaxUpload('imageUpload', {
action: $('form#newHotnessForm').attr('action'),
name: 'image',
onSubmit: function(file, extension) {
$('div.preview').addClass('loading');
},
onComplete: function(file, response) {
thumb.load(function(){
$('div.preview').removeClass('loading');
thumb.unbind();
});
thumb.attr('src', response);
}
});
});Let’s break the code down now and look at what’s really going on. First, we attach the AjaxUpload behavior to our file form element.
new AjaxUpload('imageUpload', {
Next, we specify where to post the Ajax upload. We want to keep all of our URLs in our HTML document, so we pass this URL using the action attribute of our form element.
action: $('form#newHotnessForm').attr('action'),
Set the name of the file form element that will be posted to your server.
name: 'image',
Add a class to your preview div to indicate that the image is uploading. In our case, we are applying a background image to the preview div. We also need to set the image tag to display: none; in the preview div, so that the loading background image is visible, as well as for a more subtle reason explained below.
onSubmit: function(file, extension) {
$('div.preview').addClass('loading');
},
When the image has been uploaded, we have to do two things:
- First, we have to set the
srcattribute of our previewimgtag to the new thumb. - Secondly, we have to remove the loading class. If we simply execute these things in that order, then we would see an annoying flicker of the old image when the loading class has been removed but the new image has not yet loaded.
We avoid the annoying flicker of the old image by waiting to remove the loading class until after the preview image’s load event fires. We also unbind our listener after it has fired because we want to capture this event only once.
onComplete: function(file, response) {
thumb.load(function(){
$('div.preview').removeClass('loading');
thumb.unbind();
});
Lastly, we set the source of the preview image to the thumbnail that our server has just created. In this example, the response from the Ajax call is just the thumbnail’s URL as text. You could return it in whatever fancy format you like.
thumb.attr('src', response);
}If JavaScript-support is disabled in user’s browsers, they will get the good old submit form without the interactive preview. Clean and functional solution, with rich interactions for users with more capable browsers.

Better Image Uploads
Want to try out and implement the image uploader yourself? Check out a live demo, the example code and more for this improved way to support image uploads on your website.
Validation With jQuery Text-Change Event
Here’s a pretty common problem: you have a text form to validate client-side. Doing this is easy enough when the form is submitted, but in some cases doing it as the user is typing is best. For example, imagine how annoying Twitter would be if you had to submit your tweet before you were told how many characters it was.
Keep in mind, though, that this kind of immediate validation can be overused or abused. Don’t insult the user by congratulating them for every piece of text they enter in a field.
Implementing this requires that you bind events to the keyup event — and a couple other events if you want to detect text changes on cut-and-paste events. Even if you’re a JavaScript god, having to keep writing this logic over and over again is tedious. We created a text-change event plug-in to help you handle all text-change events.
Detecting the Text (Better Than Twitter)
We begin by detecting text in the standard textarea. Look at the shot below: looks like a standard textarea with a disabled “Save” button.
If you add text to the field, then the “Save” button enables and then disables when no text is in the field. Moderately impressive, right?
Now, what if you try copying, pasting or cutting text with the shortcut keys? That works as well. What about right-clicking or using the “Edit” menu? Works, too. (By the way, Twitter doesn’t support the click or menu interactions.)
The code behind this is pretty simple. You’ll need to download and link up the textchange plug-in.
The plug-in adds the hastext and notext events, to which you can bind input and textarea elements.
$('#exhibita').bind('hastext', function () {
$('#exhibitaButton').removeClass('disabled').attr('disabled', false);
});
$('#exhibita').bind('notext', function () {
$('#exhibitaButton').addClass('disabled').attr('disabled', true);
});
The hastext event fires when the element goes from having no text to having text, and the notext event fires when the element goes from having text to being blank. Looking for more advanced validation? Keep reading.
Detecting Text Change
What about detecting text change in the field?
This is very easy, too. A third textchange event fires whenever the text changes, and it provides you with the previous value.
$('#exhibitb').bind('textchange', function (event, previousText) {
$('#output').append('
Text changed from ' +
previousText + ' to ' + $(this).val() +
' ');
});Twitter-Style Validation
We can implement some simple Twitter-like validation with just a single line and our textchange event.
$('#twitter').bind('textchange', function (event, previousText) {
$('#charactersLeft').html( 140 - parseInt($(this).val().length) );
});Ajax Save
With a little more code and setTimeout, we can hook up an Ajax call to save a few seconds once the user stops editing. The Ajax call is just stubbed out here, but you get the idea.
var timeout;
$('#ajaxSave').bind('textchange', function () {
clearTimeout(timeout);
$('#ajaxFired').html('Typing...');
var self = this;
timeout = setTimeout(function () {
$('#ajaxFired').html('Saved: ' + $(self).val());
}, 1000);
});
Validate Text
This may sound contrived, but say you would like to ensure that the two words “companion cube” are in the emergency intelligence incinerator (i.e. the text field) before allowing the user to continue. No problem:
$('#emergencyIntelligenceIncinerator').bind('textchange', function () {
if ($(this).val().indexOf('companion cube') !== -1) {
$('#continue').removeClass('disabled').attr('disabled', false);
}
});jQuery Text-Change event can be very useful for web applications that are aiming for a high level of interactivity and visual feedback. You may even want to analyze some of the input and provide helpful clues. For instance, if the user is opening a new ticket in your support area, you may want to present links to possibly related answers in the support forum. Be sure not to analyze every keystroke, though, as it could result in a significant overhead for the back-end. And it is also important to keep in mind that the immediacy of the application should be subtle and should not interrupt user’s interaction.

Text Change Events
Don’t fret about complicated validation, text events and edge cases. Check out the live demo and download the plug-in, which makes it a snap to perform a number of functions on text boxes to look for values, changes and more.
JavaScript Annotation Plug-In
An application that we recently developed (Notable) allows users to collect user feedback through interactive tools. Most of these tools require the user to annotate an image. We figured that many folks are trying to solve the same problem, so why not create a plug-in that they can use? This is the result. Our plug-in uses jQuery and makes it very simple to add and save image annotations.
To start off, download the JS Annotation Plug-In. To use the plug-in, just link up jQuery (1.2.3 or higher) and our plug-in.
Meet Nutmeg the Dog. After clicking on a random spot on Nutmeg, you’ll see the black circle appear.
function blackNote() {
return $(document.createElement('span')).addClass('black circle note')
}
$('#nutmeg').annotatableImage(blackNote);Here’s how it works: The first parameter to annotatableImage is a function that is implemented by you and that defines the element to be added when you click. In the example above, that function is called blackNote. Simple, right?
How to Save the Annotations?
Glad you asked. Use the jQuery selector to grab all the elements that you want to serialize, and call the serializeAnnotations function.
$('#nutmeg span.note').serializeAnnotations();
These values are returned in an array of objects, so you can easily save them with an Ajax call. The response_time variable is the time in milliseconds that the user took to add the annotation after you made the call to annotatableImage.
Let’s Get Relative
In our website feedback tool we needed to show our annotations in different-sized versions of our original image. The full size is just won’t always cut it in the world of good design. To make this easier, we store the x and y positions of our annotations relative to the width and height of the image.
If you didn’t pass fifth-grade math, don’t worry: our plug-in does all the basic arithmetic for you. Warning: if you change the aspect ratio or crop the image, this will not work properly. Also, be sure to always store x and y as floating-point data types.
$('#smallNutmeg').addAnnotations(blackNote, annotations);
The annotations variable is an array of objects with x and y attributes. It looks exactly like the array returned by the serializeAnnotations function without the response_time attribute. What other attributes might you put in the annotation object? Read on…
Passing Attributes
We may want to pass some data to each of our annotations when adding existing annotations. Maybe we have numbered our annotations, or have added special classes or behaviors, whatever.
The function we pass to annotatableImage accepts a single parameter, which is the annotation object from the array that you passed to addAnnotations. In this example, we added a position attribute, which we will display.
$('#numberedNutmeg').addAnnotations(function(annotation){
return $(document.createElement('span')).
addClass('black circle note').html(annotation.position);
},[
{x: 0.3875, y: 0.3246, position: 4},
{x: 0.57, y: 0.329, position: 2}
]
);Hitting All the Positions
When we were annotating Nutmeg, you may have noticed that the annotation was centered at your click position. This may be great for circles and sparkly unicorns, but sometimes we may want to position our annotations differently.
The xPosition and yPosition options allow you to indicate where the annotation is positioned relative to the click. Options are middle (default), left, right and middle (default), top, bottom, respectively.
$('#labeledNutmeg').annotatableImage(function(annotation){
return $(document.createElement('span')).addClass('set-label');
}, {xPosition: 'left'});
Give Nutmeg some clicks on our demo page to see what we’re talking about. In this example, we are positioning the click on the left side of the annotation.
Warning: make sure to pass the xPosition and yPosition to the serializeAnnotations function if you set these options in annotatableImage. The default behavior is to calculate the x and y values from the middle of the annotation.

JavaScript Annotations Plug-In
Start supporting powerful, easily implemented annotations on your website or app with this plug-in. Adding notes, descriptions and more to these annotations is simple.
Bonus: CSS Grid Builder
In our design process, we have been using a flexible grid framework that lets us rapidly prototype and implement websites. Recently, we’ve created some variant grids for different widths and gutter sizes, so we thought, why not just create grids on the fly with a simple tool?
Please feel free to use the ZURB CSS Grid Builder to build and generate source code for a simple, flexible grid framework for variable grid sizes and column numbers. Play around with it — we prefer it to a more full-featured solution such as YUI because it’s lighter and a little more flexible.

CSS Grid Builder
Check out the CSS Grid Builder in the playground. You can preview the grid in different-sized browser windows and output a complete CSS framework.
(al)
© ZURB for Smashing Magazine, 2010. | Permalink | Post a comment | Add to del.icio.us | Digg this | Stumble on StumbleUpon! | Tweet it! | Submit to Reddit | Forum Smashing Magazine
Post tags: CSS, jquery, js
: The Genius of the Lego PrinterSlashdot
Read more of this story at Slashdot.
: Quick Tip: Google Fonts API: You’re Going to Love ThisNettuts+
Google have made two huge announcements today. One of these concerns the Google Fonts API. Simply by linking to a particular font, stored on Google’s servers (save on bandwidth + caching benefits), we now have access to a wide array of custom fonts. Quite literally, you can integrate these fonts into your project in about 20 seconds. It’s as simple as that. Further, due to the operations being performed behind the scenes, these custom fonts will even be recognized back to Internet Explorer 6. I, for one, and am extremely excited about the possibilities, and the font catalog is surely to continue expanding over the coming years.
Subscribe to our YouTube page to watch all of the video tutorials!
Prefer to watch this video on Screenr.com?
One Step Only
To take advantage of the Google Fonts API, you only need to link to your desired font, and reference it within font-family. That’s it! When you find yourself integrating a custom font in less than 15 seconds, you’ll laugh with joy! For example:
untitled Hello World

Crazy, isn’t it!? You can refer here for the current list of available fonts. So what do you think?
: Sacked and fined £1,000 for a joke about an airport? | David Mitchell columnGlobal: David Mitchell | guardian.co.uk
The case of the man interrogated for seven hours for a silly quip he made on Twitter shows a depressing sense of humour failure
We live in serious times. Humanity is facing terrifying threats to its future, as usual. Most of them are self-induced, as usual. Britain feels itself to be on a precipice, about to plunge into a new canyon of mediocrity and self-chastisement, as usual. There are serious fears about disruption to people's holiday plans over the half-term break, as usual.
What is unusual is that this seriousness is being compounded by an intensifying national determination to behave terribly seriously about it. No one's buying frivolity or flippancy stocks at the moment. Piss-taking is falling on all markets and everyone's pouring their rhetorical investments into beard-stroking bonds, head-shaking futures and survivor's gilts.
Paul Chambers knows this to his cost. During the January snows, his hopes of a blind date with a woman he'd chatted up on Twitter were jeopardised by the closure of his local airport. He tweeted from his mobile to his 600 followers: "Crap! Robin Hood airport is closed. You've got a week and a bit to get your shit together, otherwise I'm blowing the airport sky high!" He was subsequently arrested, interrogated by detectives for seven hours and fired from his accountancy job. Last week he was found guilty of sending a menacing electronic message and fined £1,000.
In the heady days of the boom, perhaps I'd have been inclined to laugh at this unfortunate idiot, pictured in the paper looking dazed and unshaven, tie at half-mast, still clutching his treacherous iPhone. He's executed a perfect and extravagant online pratfall – he's like a cyber-Frank Spencer – but, in the spirit of this serious age, I just feel terribly sorry for him. I'm not amused, I'm annoyed.
That's an attitude I suspect I share with the off-duty airport manager who spotted the tweet and informed security. He or she might have thought: "That's not funny. I work at an airport – what's funny about blowing it up? I'm going to take this further." But maybe it was more like: "I appreciate the dark humour of this frustrated remark but am duty-bound, under current security protocols, to pass this on to my superiors who, this being a sane world, will presumably ignore it."
What I can't believe is that anyone thought the message was a genuine expression of violent intent. I don't know much about al-Qaeda's MO but I imagine giving a week's warning of an attack, in the guise of an irritable and amorous accountant, would amount to a significant change in tactics.
Certainly, the threat – and I suppose it is theoretically a threat, in the same way that an aspirin is a food and George Osborne a successor to Gladstone – was classified as "not credible" by the airport. I don't know if that means they thought it was funny. Maybe these people sit in front of Morecambe and Wise, sides splitting, tears streaming down their faces, yelling "Not credible!" as Eric picks up André Previn by the lapels.
However, despite Chambers's manifest lack of credibility, the security people were apparently obliged to inform South Yorkshire police, who arrested him a week later. They were obviously convinced he was a man of his word in terms of the week-and-a-bit timescale. With many plausible terrorist threats, they might have rushed straight round there. Or maybe they're not morons and knew perfectly well that he had no intention of blowing up an airport but had decided to make an example of him.
It's vindictive and it's humourless. Could they not just have had a quiet word? Was bringing him to trial really in the public interest? Is a large fine, unemployment and a criminal record proportionate punishment for an irritated quip, albeit one made within the earshot of others? He didn't actually send the message to the airport, written in letters cut out from a newspaper, wrapped round a raw liver and a holy text (Christian, Muslim or SMS).
Or did some people resent his levity? While not deemed a threat, was his tweet considered "inappropriate" by those who had the means to elevate inappropriateness to a criminal offence? "In a world where people do try to blow up airports, such a remark can never be funny," they think. They've got it backwards: it's funny because such terrorists exist. If they didn't, it would just be wacky, like saying: "They've got a week and a bit or I'll cover the runway with jelly!" (not Napalm).
This aversion to levity certainly infused the election campaign. But there was a funny bit and most of us missed it. When Gordon Brown got in his car and called that woman a bigot, it was hilarious. It was a properly comical human moment, made funnier by the uncomfortable truths it hit upon, in terms of both the former PM's flawed personality and the jealous xenophobia that lurks behind many discussions of immigration.
But we forgot to laugh, because some of us have come to prefer the sensation of judging: judging Brown for the gaffe, judging the media for its reporting of it, poring po-facedly over the subsequent pantomime of apology. It was the equivalent of his accidentally showing his arse and yet all we could do was carp: "Has he been concealing from the public quite how fat his arse really is?" or: "Why, at this moment of crisis, are our media focusing on arses rather than policies?" No one said: "Ha ha! I can see his arse!"
Instead of finding genuine humour, we're expected to stomach the ersatz jokes that the leaders prepared for the debates, like Brown's "They remind me of my two young boys squabbling at bath time!" line – official moments of respectful jocularity, the humorous equivalents of a maiden aunt's one cream sherry every Christmas. And this in a country that used to like getting pissed.
We already live in a world where, when asked whether we've packed our own bags, we know that saying: "Yes, I put all the bombs in myself!" will not be taken in good humour; where a conversation with a US immigration official must be treated with all the piety of an audience with the pope. We have accepted that facetiousness, like smoking, while not officially illegal, is absolutely not for public places.
Well, I don't remember agreeing to it and I'm sick of it. It's boring, I don't believe it saves a single life and it could do incalculable damage to freedom of speech. I'm serious.
: Last flight of the Space Shuttle AtlantisFlickr Blog
Photos from JohnMilleker.com, pea g. | [really catching up now!], danni deer, DaveDoop, tkrphoto, and Kyle Hickman.
: VI Editor / Linux Terminal Cheat Sheet (PDF)Smashing Magazine Feed
We’ve been releasing many icon sets and WordPress themes on Smashing Magazine, yet today we are glad to announce the release of a bit different freebie. This post features a VI Help Sheet, a cheat sheet for the VI Editor, for all web-developers out there who are working on Linux. The help sheet was designed by GoSquared and released for Smashing Magazine and its readers.
The cheat sheet contains terminal commands for modes and controls, inserting text, cursor navigation, deleting text, searching and replacing. Download it. Print it. Stick it on the wall and get commanding.
Download the cheat sheet for free!
- large preview
- download the PDF-file (updated, 0.5 Mb)
- release post on the designers’ page
Behind the design
As always, here are some insights from the designers:
We created the VI Editor cheat sheet because of the amount of time members of our team spend working in the Linux Terminal. Working on our web app is a full time occupation and for the developers, using the command line 24/7 can be exhausting. Forgetting a command here or there can really break up their workflow. So we put together the VI cheat sheet that can be used for quick reference as and when you need!
Thank you, guys. We really appreciate your work and your good intentions.
© Smashing Editorial for Smashing Magazine, 2010. | Permalink | 42 comments | Add to del.icio.us | Digg this | Stumble on StumbleUpon! | Tweet it! | Submit to Reddit | Forum Smashing Magazine
Post tags: Freebies
: CSS 2.1 and CSS 3 Help Cheat Sheets (PDF)Smashing Magazine Feed
Today we are glad to release two useful cheat sheets that will help you quickly look up the right CSS 2.1-property or an obscure CSS 3 property. The style sheets contain most important properties, explanations and keywords for each property. The help sheets were created by GoSquared and released for Smashing Magazine and its readers.
Download the cheat sheets for free!
The CSS 2.1 Help Sheet covers Syntax, Font, Text, Margins, Padding, Border, Position, Background, List, Media Types and Keywords. The CSS 3 Help Sheet contains code snippets for Rounded Corners, Box Shadow, Multiple Columns, Text Shadow, RGBa, Font Face (actually, not the CSS3 property, but still include for the sake of usefulness), Box Sizing, Box Resize, Outline and Gradients.
- CSS 2.1 Sheet (large preview)
- CSS 3 Sheet (large preview)
- download the CSS 2.1 Sheet (PDF) (0.2 Mb)
- download the CSS 3 Sheet (PDF) (updated, 0.2 Mb)
- release post on the designers’ page
Behind the design
As always, here are some insights from the designers:
“We created the original CSS Help Sheet because we spent ages staring at ugly cheat sheets while designing beautiful sites. So we thought we’d make a Help Sheet that didn’t hurt the eyes of anyone who tried to use it. The past year, we’ve found ourselves using more and more CSS3 methods, and there was never much in the way of help out there until we decided to create a Help Sheet specifically for CSS3.
We’ve kept CSS2 and CSS3 on separate Help Sheets for now as not everything in CSS3 is finalised, or works in all browsers (cough, IE).
We hope you enjoy using them, and that they help you create even more memorable, usable, and stylish websites.
Thank you, guys. We really appreciate your work and your good intentions.
[Offtopic: by the way, did you know that Smashing Magazine has one of the most influential and popular Twitter accounts? Join our discussions and get updates about useful tools and resources — follow us on Twitter!]
Related Posts
You may be interested in the following related posts:
- VI Editor / Linux Terminal Cheat Sheet (PDF)
- Photoshop Keyboard Shortcuts Cheat Sheet (PDF)
- HTML 5 Cheat Sheet (PDF)
- Detailed CSS 3 Cheat Sheet (PDF)
© Smashing Editorial for Smashing Magazine, 2010. | Permalink | 64 comments | Add to del.icio.us | Digg this | Stumble on StumbleUpon! | Tweet it! | Submit to Reddit | Forum Smashing Magazine
Post tags: Freebies
: Google Releases a Web-App Case Study For HackersSlashdot
Read more of this story at Slashdot.
: Happy Earth Day down there!Flickr Blog
To celebrate Earth Day, the NASA Goddard Space Flight Center has uploaded some of their favorite images of the planet we all share. Enjoy the view!
: Seven JavaScript Things I Wish I Knew Much Earlier In My CareerSmashing Magazine Feed
I’ve been writing JavaScript code for much longer than I care to remember. I am very excited about the language’s recent success; it’s good to be a part of that success story. I’ve written dozens of articles, book chapters and one full book on the matter, and yet I keep finding new things. Here are some of the “aha!” moments I’ve had in the past, which you can try out rather than waiting for them to come to you by chance.
[By the way, did you know we have a brand new free Smashing Email Newsletter? Subscribe now and get fresh short tips and tricks on Tuesdays!]
Shortcut Notations
One of the things I love most about JavaScript now is shortcut notations to generate objects and arrays. So, in the past when we wanted to create an object, we wrote:
var car = new Object(); car.colour = 'red'; car.wheels = 4; car.hubcaps = 'spinning'; car.age = 4;
The same can be achieved with:
var car = {
colour:'red',
wheels:4,
hubcaps:'spinning',
age:4
}Much shorter, and you don’t need to repeat the name of the object. Right now, car is fine, but what happens when you use invalidUserInSession? The main gotcha in this notation is IE. Never ever leave a trailing comma before the closing curly brace or you’ll be in trouble.
The other handy shortcut notation is for arrays. The old school way of defining arrays was this:
var moviesThatNeedBetterWriters = new Array( 'Transformers','Transformers2','Avatar','Indiana Jones 4' );
The shorter version of this is:
var moviesThatNeedBetterWriters = [ 'Transformers','Transformers2','Avatar','Indiana Jones 4' ];
The other thing about arrays is that there is no such thing as an associative array. You will find a lot of code examples that define the above car example like so:
var car = new Array(); car['colour'] = 'red'; car['wheels'] = 4; car['hubcaps'] = 'spinning'; car['age'] = 4;
This is not Sparta; this is madness—don’t bother with this. “Associative arrays” is a confusing name for objects.
Another very cool shortcut notation is the ternary notation for conditions. So, instead of the following…
var direction;
if(x < 200){
direction = 1;
} else {
direction = -1;
}… You could write a shorter version using the ternary notation:
var direction = x < 200 ? 1 : -1;
The true case of the condition is after the question mark, and the other case follows the colon.
JSON As A Data Format
Before I discovered JSON to store data, I did all kinds of crazy things to put content in a JavaScript-ready format: arrays, strings with control characters to split, and other abominations. The creation of JSON by Douglas Crockford changed all that. Using JSON, you can store complex data in a format that is native to JavaScript and doesn't need any extra conversion to be used immediately.
JSON is short for "JavaScript Object Notation" and uses both of the shortcuts we covered earlier.
So, if I wanted to describe a band, for example, I could do the following:
var band = {
"name":"The Red Hot Chili Peppers",
"members":[
{
"name":"Anthony Kiedis",
"role":"lead vocals"
},
{
"name":"Michael 'Flea' Balzary",
"role":"bass guitar, trumpet, backing vocals"
},
{
"name":"Chad Smith",
"role":"drums,percussion"
},
{
"name":"John Frusciante",
"role":"Lead Guitar"
}
],
"year":"2009"
}You can use JSON directly in JavaScript and, when wrapped in a function call, even as a return format of APIs. This is called JSON-P and is supported by a lot of APIs out there. You can use a data endpoint, returning JSON-P directly in a script node:
This calls the Delicious Web service to get my latest JavaScript bookmarks in JSON format and then displays them as an unordered list.
In essence, JSON is probably the most lightweight way of describing complex data—and it runs in a browser. You can even use it in PHP using the json_decode() function.
Native JavaScript Functions (Math, Array And String)
One thing that amazed me is how much easier my life got once I read up thoroughly on the math and string functions of JavaScript. You can use these to avoid a lot of looping and conditions. For example, when I had the task of finding the largest number in an array of numbers, I used to write a loop, like so:
var numbers = [3,342,23,22,124]; var max = 0; for(var i=0;imax){ max = numbers[i]; } } alert(max);
This can be achieved without a loop:
var numbers = [3,342,23,22,124];
numbers.sort(function(a,b){return b - a});
alert(numbers[0]);Notice that you cannot use sort() on a number array because it sorts lexically. There's a good tutorial on sort() here in case you need to know more.
Another interesting method is Math.max(). This one returns the largest number from a list of parameters:
Math.max(12,123,3,2,433,4); // returns 433
Because this tests for numbers and returns the largest one, you can use it to test for browser support of certain properties:
var scrollTop= Math.max( doc.documentElement.scrollTop, doc.body.scrollTop );
This works around an Internet Explorer problem. You can read out the scrollTop of the current document, but depending on the DOCTYPE of the document, one or the other property is assigned the value. When you use Math.max() you get the right number because only one of the properties returns one; the other will be undefined. You can read more about shortening JavaScript with math functions here.
Other very powerful functions to manipulate strings are split() and join(). Probably the most powerful example of this is writing a function to attach CSS classes to elements.
The thing is, when you add a class to a DOM element, you want to add it either as the first class or to already existing classes with a space in front of it. When you remove classes, you also need to remove the spaces (which was much more important in the past when some browsers failed to apply classes with trailing spaces).
So, the original function would be something like:
function addclass(elm,newclass){
var c = elm.className;
elm.className = (c === '') ? newclass : c+' '+newclass;
}You can automate this using the split() and join() methods:
function addclass(elm,newclass){
var classes = elm.className.split(' ');
classes.push(newclass);
elm.className = classes.join(' ');
}This automatically ensures that classes are space-separated and that yours gets tacked on at the end.
Event Delegation
Events make Web apps work. I love events, especially custom events, which make your products extensible without your needing to touch the core code. The main problem (and actually one of its strengths) is that events are removed from the HTML—you apply an event listener to a certain element and then it becomes active. Nothing in the HTML indicates that this is the case though. Take this abstraction issue (which is hard for beginners to wrap their heads around) and the fact that "browsers" such as IE6 have all kind of memory problems and too many events applied to them, and you'll see that not using too many event handlers in a document is wise.
This is where event delegation comes in. When an event happens on a certain element and on all the elements above it in the DOM hierarchy, you can simplify your event handling by using a single handler on a parent element, rather than using a lot of handlers.
What do I mean by that? Say you want a list of links, and you want to call a function rather than load the links. The HTML would be:
Great Web resources
- Opera Web Standards Curriculum
- Sitepoint
- A List Apart
- YUI Blog
- Blame it on the voices
- Oddly specific
The normal way to apply event handlers here would be to loop through the links:
// Classic event handling example
(function(){
var resources = document.getElementById('resources');
var links = resources.getElementsByTagName('a');
var all = links.length;
for(var i=0;iThis could also be done with a single event handler:
(function(){
var resources = document.getElementById('resources');
resources.addEventListener('click',handler,false);
function handler(e){
var x = e.target; // get the link tha
if(x.nodeName.toLowerCase() === 'a'){
alert('Event delegation:' + x);
e.preventDefault();
}
};
})();Because the click happens on all the elements in the list, all you need to do is compare the nodeName to the right element that you want to react to the event.
Disclaimer: while both of the event examples above work in browsers, they fail in IE6. For IE6, you need to apply an event model other than the W3C one, and this is why we use libraries for these tricks.
The benefits of this approach are more than just being able to use a single event handler. Say, for example, you want to add more links dynamically to this list. With event delegation, there is no need to change anything; with simple event handling, you would have to reassign handlers and re-loop the list.
Anonymous Functions And The Module Pattern
One of the most annoying things about JavaScript is that it has no scope for variables. Any variable, function, array or object you define that is not inside another function is global, which means that other scripts on the same page can access—and will usually override— them.
The workaround is to encapsulate your variables in an anonymous function and call that function immediately after you define it. For example, the following definition would result in three global variables and two global functions:
var name = 'Chris';
var age = '34';
var status = 'single';
function createMember(){
// [...]
}
function getMemberDetails(){
// [...]
}Any other script on the page that has a variable named status could cause trouble. If we wrap all of this in a name such as myApplication, then we work around that issue:
var myApplication = function(){
var name = 'Chris';
var age = '34';
var status = 'single';
function createMember(){
// [...]
}
function getMemberDetails(){
// [...]
}
}();This, however, doesn't do anything outside of that function. If this is what you need, then great. You may as well discard the name then:
(function(){
var name = 'Chris';
var age = '34';
var status = 'single';
function createMember(){
// [...]
}
function getMemberDetails(){
// [...]
}
})();If you need to make some of the things reachable to the outside, then you need to change this. In order to reach createMember() or getMemberDetails(), you need to return them to the outside world to make them properties of myApplication:
var myApplication = function(){
var name = 'Chris';
var age = '34';
var status = 'single';
return{
createMember:function(){
// [...]
},
getMemberDetails:function(){
// [...]
}
}
}();
// myApplication.createMember() and
// myApplication.getMemberDetails() now works.
This is called a module pattern or singleton. It was mentioned a lot by Douglas Crockford and is used very much in the Yahoo User Interface Library YUI. What ails me about this is that I need to switch syntaxes to make functions or variables available to the outside world. Furthermore, if I want to call one method from another, I have to call it preceded by the myApplication name. So instead, I prefer simply to return pointers to the elements that I want to make public. This even allows me to shorten the names for outside use:
var myApplication = function(){
var name = 'Chris';
var age = '34';
var status = 'single';
function createMember(){
// [...]
}
function getMemberDetails(){
// [...]
}
return{
create:createMember,
get:getMemberDetails
}
}();
//myApplication.get() and myApplication.create() now work.I've called this "revealing module pattern."
Allowing For Configuration
Whenever I've written JavaScript and given it to the world, people have changed it, usually when they wanted it to do things that it couldn't do out of the box—but also often because I made it too hard for people to change things.
The workaround is to add configuration objects to your scripts. I've written about JavaScript configuration objects in detail, but here's the gist:
- Have an object as part of your whole script called
configuration. - In it, store all of the things that people will likely change when they use your script:
- CSS ID and class names;
- Strings (such as labels) for generated buttons;
- Values such as "number of images being displayed," "dimensions of map";
- Location, locale and language settings.
- Return the object as a public property so that people can override it.
Most of the time you can do this as a last step in the coding process. I've put together an example in "Five things to do to a script before handing it over to the next developer."
In essence, you want to make it easy for people to use your code and alter it to their needs. If you do that, you are much less likely to get confusing emails from people who complain about your scripts and refer to changes that someone else actually did.
Interacting With The Back End
One of the main things I learned from all my years with JavaScript is that it is a great language with which to make interactive interfaces, but when it comes to crunching numbers and accessing data sources, it can be daunting.
Originally, I learned JavaScript to replace Perl because I was sick of copying things to a cgi-bin folder in order to make it work. Later on, I learned that making a back-end language do the main data churning for me, instead of trying to do all in JavaScript, makes more sense with regard to security and language.
If I access a Web service, I could get JSON-P as the returned format and do a lot of data conversion on the client, but why should I when I have a server that has a richer way of converting data and that can return the data as JSON or HTML… and cache it for me to boot?
So, if you want to use AJAX, learn about HTTP and about writing your own caching and conversion proxy. You will save a lot of time and nerves in the long run.
Browser-Specific Code Is A Waste Of Time. Use Libraries!
When I started Web development, the battle between using document.all and using document.layers as the main way to access the document was still raging. I chose document.layers because I liked the idea of any layer being its own document (and I had written more than enough document.write solutions to last a lifetime). The layer model failed, but so did document.all. When Netscape 6 went all out supporting only the W3C DOM model, I loved it, but end users didn't care. End users just saw that this browser didn't show the majority of the Internets correctly (although it did)—the code we produced was what was wrong. We built short-sighted code that supported a state-of-the-art environment, and the funny thing about the state of the art is that it is constantly changing.
I've wasted quite some time learning the ins and outs of all of the browsers and working around their issues. Doing this back then secured my career and ensured that I had a great job. But we shouldn't have to go through this trial by fire any longer.
Libraries such as YUI, jQuery and Dojo are here to help us with this. They take on the problems of browsers by abstracting the pains of poor implementation, inconsistencies and flat-out bugs, and relieve us of the chore. Unless you want to beta test a certain browser because you're a big fan, don't fix browser issues in your JavaScript solutions, because you are unlikely to ever update the code to remove this fix. All you would be doing is adding to the already massive pile of outdated code on the Web.
That said, relying solely on libraries for your core skill is short-sighted. Read up on JavaScript, watch some good videos and tutorials on it, and understand the language. (Tip: closures are God's gift to the JavaScript developer.) Libraries will help you build things quickly, but if you assign a lot of events and effects and need to add a class to every HTML element in the document, then you are doing it wrong.
Resources
In addition to the resources mentioned in this article, also check out the following to learn more about JavaScript itself:
- Douglas Crockford on JavaScript
An in-depth video Lecture series. - The Opera Web Standards Curriculum
With a detailed section on JavaScript.
Related Posts
You may be interested in the following related posts:
- The Seven Deadly Sins Of JavaScript Implementation
- Developing Sites With AJAX: Design Challenges and Common Issues
- 45 Powerful CSS/JavaScript-Techniques
(al)
© Christian Heilmann for Smashing Magazine, 2010. | Permalink | 132 comments | Add to del.icio.us | Digg this | Stumble on StumbleUpon! | Tweet it! | Submit to Reddit | Forum Smashing Magazine
Post tags: javascript, js
: Check me out…I’m dancin’…I’m dancin’ ! Here are your Claptrap WAV filesXbox Live's Major Nelson
Thanks to our good friends at Gearbox software, I present thee with a few official Claptrap sounds from Borderlands. Use them to make a ringtone, text alert messages, new mail notification and more. Here is a 3.9 MB.ZIP file that contains 16 classic Claptrap clips.
Note: These audio clips are provided for personal, non-commercial use only!
: alistair darlingB3ta Best of the Board
via by The_Fiend on 2010-04-09
yes i know b3ta isn't lulcats but this was applicable
: Fine Print Says Game Store Owns Your SoulSlashdot
Read more of this story at Slashdot.
: What Chernobyl Looks Like In 2010Slashdot
Read more of this story at Slashdot.
: Google April Fools' Day 2010Google Operating System
Google Japan developed a special version of Google Voice Search for animals. Unfortunately, Google Translate is not very helpful:
"For this animal, the dog still, cats, pigeons are just the future, cows and horses, hamsters, frogs, and plans to expand into. Voice Search a variety of potential animal, you try all means, exchange'd appreciate help with animals. Google's mission is to organize the world's information and make it universally accessible and useful to the people around the world. You are also feeling the animal to be able to access, will continue to continue research, and Nakajima are saying."
There's also Google Translate for Animals, a new Android application that "allows you to record animals sounds and have the sounds analyzed and translated by Google Translate into any of the 52 supported languages".
Google Australia is now able to "Optimise for Colloquial Cultural Articulation (OCCA) - which means our products can now be tailored specifically for the typical Strayan user. (...) OCCA greatly reduces the latency between a user's thought and ability to pinpoint information; a boon for local users who'd have Buckleys makin' sense of American English."

Google Street View is now available in 3D, but you need to click on an icon to go 3D:

Google decided to change its name to Topeka, the US city that intends to change its name to Google.

Google's search results pages use some interesting units of measurements to estimate how long it took Google to obtain the results: Plunk, gigawatts, warp, centibeats, skidoo, femtogalactic years, velocity of an unladen swallow.

YouTube has a new text-only mode: TEXTp. "It's great news that there are 24 hours of video uploaded to YouTube every minute, we support 1080p and HD uploads are rising quickly, but that's also meant increasing bandwidth costs cutting into our bottom line. (...) TEXTp is the result of months of intense transcoding efforts by our engineers, who toiled for weeks to ensure that a large chunk of videos on the platform could be reduced to their most basic elements. By replacing the images in the video with a series of letters and numbers, the videos are far less taxing on our system -- and have the added benefit of promoting literacy!"
You can try the new mode by appending &textp=fool to YouTube URLs (like this).

Google Docs lets you store ANYTHING. "Ever wish you could CTRL+F your keys? Store your keys and other objects you commonly lose with Google and you'll never have to worry about finding them again. We're testing a new mail courier network integrated with our Street View fleet. We'll show up within 3 hours to pick up anything you choose to store in Google Docs, guaranteed. At $0.10 per kg, you can store a grand piano for the price of lunch."
Google Voice added a standard voicemail mode.
Standard Voicemail Mode brings your voicemail back to something reminiscent of 1997, with features like:
* Automatic voicemail deletion: messages will be deleted automatically after 14 days
* Numeric keypad access: access to voicemail will only be available via your phone
* Beeper interoperability: your beeper will be paged every time a voicemail is left
* Message maximums: store a maximum of 10 messages at any given time
* Numeric page: people leaving you voicemails will be given the option to send a numeric page
Google Mobile Search found a way to return better results for queries like "where am I". Try this query on your mobile phone and you'll find a lot of interesting results:

Gmail's login page no longer uses vowels and greets users with a short message: "Wlcm t Gml".


















![[134/365] STS-132: Atlantis Shuttle Launch](http://farm4.static.flickr.com/3354/4607739912_5bfba83942.jpg)

























