67
taken by Jeremy Keith - http://www.flickr.com/photos/adactio/ Writing jQuery JavaScript that doesn’t suck

Writing JavaScript that doesn't suck

Embed Size (px)

DESCRIPTION

Presented at London Web Standards Pick 'n' Mix, 18th January 2011 Numerous tips and advice on writing JavaScript code that avoids most common pitfalls, is unmaintainable, inaccessible or slow as a dog. Futher explanation and links to articles mentioned can be found at http://rossbruniges.posterous.com/

Citation preview

Page 1: Writing JavaScript that doesn't suck

taken by Jeremy Keith - http://www.flickr.com/photos/adactio/

Writing jQuery JavaScript that doesn’t suck

Page 2: Writing JavaScript that doesn't suck

Ross Bruniges

Introductions

Page 3: Writing JavaScript that doesn't suck

Introductions

taken by Phil Whiteside - http://www.flickr.com/photos/philliecasablanca/

Ross Bruniges, Web Developer at Nature.com

Page 4: Writing JavaScript that doesn't suck

Introductions

Ross Bruniges, Occasional Author

Page 5: Writing JavaScript that doesn't suck

taken by Patrick Griffiths - http://www.flickr.com/photos/ptg/

Ross Bruniges, Regular drinker at Pub Standards

Introductions

Page 6: Writing JavaScript that doesn't suck

taken by Caz Mockett - http://www.flickr.com/photos/rugbymadgirl/

So what am I going to be talking about?

Introductions

Page 7: Writing JavaScript that doesn't suck

taken by PJ Barry - http://www.flickr.com/photos/actel/

A new years refresher after a long 2010

Introductions

Page 8: Writing JavaScript that doesn't suck

taken by Julian Burgess - http://www.flickr.com/photos/aubergene/

A JavaScript mixed bag.

Introductions

Page 9: Writing JavaScript that doesn't suck

Yes this is my wardrobe

Organisation

Page 10: Writing JavaScript that doesn't suck

Remember to use eventDelegationLint your JavaScript

Organisation

JSLint is a JavaScript program that looks for problems in JavaScript programs. It is a code quality tool.

More information on the JS Lint at http://www.jslint.com/lint.html

Page 11: Writing JavaScript that doesn't suck

Remember to use eventDelegationBeware global variables, they are easy to overwrite

Organisation

application = some large JS app (global)

function eatMe() {

// accessing the global variable

application = false;

}

eatMe();

application.shouldWork();// now returns false

Page 12: Writing JavaScript that doesn't suck

Remember to use eventDelegationBeware global variables, they are easy to overwrite

Organisation

application = some large JS app (global)

function eatMe() {

// now accessing a local variable

var application = false;}

eatMe();

application.shouldWork()// now works

Page 13: Writing JavaScript that doesn't suck

Remember to use eventDelegationDon’t rely on semi-colon insertion to work

Organisation

return{ javascript : "fantastic"};

Example by Douglas Crockford

Page 14: Writing JavaScript that doesn't suck

Remember to use eventDelegationDon’t rely on semi-colon insertion to work

Organisation

return; // Semicolon inserted, believing the statement has finished. Returns undefined{ // Considered to be an anonymous block, doing nothing javascript : "fantastic"};// Semicolon interpreted as an empty dummy line and moved down

Example by Douglas Crockford

Page 15: Writing JavaScript that doesn't suck

Remember to use eventDelegationHug your brackets and remember to include your semi-colons

Organisation

return { javascript : "fantastic"};

Example by Douglas Crockford

Page 16: Writing JavaScript that doesn't suck

Remember to use eventDelegationAlways use === and !==

Organisation

1 == true // returns true as 1 is a ‘truthy’ value and gets converted to such

1 === true // returns false as no conversion is applied

Page 17: Writing JavaScript that doesn't suck

Remember to use eventDelegationDo it for Douglas

Organisation

More Crockford facts at http://crockfordfacts.com/

Page 18: Writing JavaScript that doesn't suck

Remember to use eventDelegationAvoid long chained statements - just because you can doesn’t mean that you should.

Organisation

$(‘#foo’).click(function(){console.log(‘please stop this madness’);}).end().filter(‘div.urgghhh’)

Pain for someone down the line

Page 19: Writing JavaScript that doesn't suck

Remember to use eventDelegationEveryone likes a nice chain

Organisation

Page 20: Writing JavaScript that doesn't suck

Remember to use eventDelegationBut you can end up looking like a douche if you get too much

Organisation

Page 21: Writing JavaScript that doesn't suck

Remember to use eventDelegationThis works just fine

Organisation

$(‘#foo’)

.click(function(){

console.log(‘please stop this madness’);

})

.end()

.filter(‘div.urgghhh’);

Page 22: Writing JavaScript that doesn't suck

Remember to use eventDelegationMake use of a JS Design Pattern

Organisation

Page 23: Writing JavaScript that doesn't suck

Remember to use eventDelegationRevealing Module Pattern - clean, tidy and easy to understand

Organisation

var clean = function() {

var debug = false;

var init = function() {

console.log(‘fail’);

};

return {

init : init

};

}();

clean.init();

Page 24: Writing JavaScript that doesn't suck

Remember to use eventDelegationFree book!

Organisation

http://addyosmani.com/blog/essentialjsdesignpatterns/

Page 25: Writing JavaScript that doesn't suck

Remember to use eventDelegationAvoid over complication

Organisation

Page 26: Writing JavaScript that doesn't suck

Remember to use eventDelegationJust because you THINK it might be cool doesn’t mean it will be. Especially if no one has asked for it.

Organisation

Page 27: Writing JavaScript that doesn't suck

Remember to use eventDelegationDon’t stuff your functions until they burst

Organisation

function poorlyThoughtOut() { // OK I’m going to get some elements // add a class or two // parse some data from the elements // remove some DOM elements // parse some data from someplace else // fade the background to yellow to highlight the change // update the screenreader buffer}

Page 28: Writing JavaScript that doesn't suck

Remember to use eventDelegationSmaller functions are easier to understand and more modular

Organisation

function parseData() {}

function updateBuffer() {}

function betterPlanned() { // OK I’m going to get some elements // add a class or two // parseData() // remove some DOM elements // parseData() // updateBuffer()}

Page 29: Writing JavaScript that doesn't suck

Remember to use eventDelegationCustom events to allow for future development

Organisation

In your code trigger an event

$.trigger(‘carousel_move’);

If someone needs it they can use it later

$.bind(‘carousel_move’, function(e) {

console.log(‘event functionality without needing to alter the existing code base’);

});

Page 30: Writing JavaScript that doesn't suck

Remember to use eventDelegationComment your code

Organisation

// // Dear maintainer:// // Once you are done trying to 'optimize' this routine,// and have realized what a terrible mistake that was,// please increment the following counter as a warning// to the next guy:// // total_hours_wasted_here = 39//

comment from stackoverflow thread - http://stackoverflow.com/questions/184618/

Page 31: Writing JavaScript that doesn't suck

Remember to use eventDelegationJSDocToolkit - comments in, documentation out

Organisation

/** * Change the role of the employee. * @param {integer} employeeId The id of the employee. * @param {string} [newRole] The new role of the employee. */function recast(employeeId, newRole) {}

project homepage at http://code.google.com/p/jsdoc-toolkit/

Page 32: Writing JavaScript that doesn't suck

Remember to use eventDelegationDocumentation-Driven Design, document first code second

Organisation

full article by Frances Berriman at http://24ways.org/2010/documentation-driven-design-for-apis

/*@name vehicle.Sled#reindeer@function@description Set the reindeer that will pull Santa's sled.@param {string[]} reindeer A list of the reindeer.@example// specifying some reindeerSled().reindeer(['Dasher', 'Dancer', 'Rudolph', 'Vixen']);*/

Page 33: Writing JavaScript that doesn't suck

Remember to use eventDelegationWhatever you choose ensure you do it from the start.

Organisation

// TODO: Fix this. Fix what?

comment from stackoverflow thread - http://stackoverflow.com/questions/184618/

Page 34: Writing JavaScript that doesn't suck

Remember to use eventDelegationKeep it up to date

Organisation

/** * Always returns true. */public boolean isAvailable() { return false;}

comment from stackoverflow thread - http://stackoverflow.com/questions/184618/

Page 35: Writing JavaScript that doesn't suck

Performance

diagram from http://www.sapdesignguild.org/

Page 36: Writing JavaScript that doesn't suck

Don’t prematurely optimise - you’re just ASSuming

Performance

taken by pi.kappa - http://www.flickr.com/photos/27890120@N08/

Page 37: Writing JavaScript that doesn't suck

Write good selectors (sizzle parse right to left - in IE6 and 7)

Performance

$(‘#foo div’) = bad, it will search first for ALL divs in the document;

$(‘div.me’) is better it will only search for divs with that specific class

$(‘div#me’) = best, all JS parses will look only for that specific element

Page 38: Writing JavaScript that doesn't suck

Cache quicker for reuse

Performance

var expensive-selector = $(“.section:first”), reused-json-object = $.getJSON(‘docs.json’), reusable-regex = /d(b+)d/g;

Page 39: Writing JavaScript that doesn't suck

Exit quickly to avoid silent fails

Performance

Page 40: Writing JavaScript that doesn't suck

Exit quickly to avoid silent fails

Performance

var elm = $(‘#findMe’);

if (!elm.length) { return false; }

We now know that this code will only be run if the element actually exists.

Page 41: Writing JavaScript that doesn't suck

Remember to use eventDelegation

Performance

from The Mysteries of JavaScript Fu, Dan Webb - http://www.slideshare.net/danwrong/java-script-fu-

Page 42: Writing JavaScript that doesn't suck

Remember to use eventDelegation

PerformancePerformance

.live() example - quick and dirty

$('tr').live('click', function(event) { // this == tr element});

Remember to use eventDelegationCode examples from http://brandonaaron.net/blog/2010/03/4/event-delegation-with-jquery

Page 43: Writing JavaScript that doesn't suck

Remember to use eventDelegation

PerformancePerformance

.delegate() example - also chainable

$('table').delegate('tr', 'click', function(event){ // this == tr element});

Remember to use eventDelegationCode examples from http://brandonaaron.net/blog/2010/03/4/event-delegation-with-jquery

Page 44: Writing JavaScript that doesn't suck

Remember to use eventDelegation

PerformancePerformance

Handrolled example - maximum control

$('table').bind('click', function(event) { // this == table element var $tr = $(event.target).closest('tr');});

Remember to use eventDelegationCode examples from http://brandonaaron.net/blog/2010/03/4/event-delegation-with-jquery

Page 45: Writing JavaScript that doesn't suck

Remember to use eventDelegation

PerformancePerformance

Cause minimal reflows and repaints (especially in IE)

Page 46: Writing JavaScript that doesn't suck

Remember to use eventDelegation

PerformancePerformance

RepaintsQuote from http://dev.opera.com/articles/view/efficient-javascript/?page=all

“Repaint - also known as redraw - is what happens whenever something is made visible when it was not previously visible, or vice versa, without altering the layout of the document.”

Page 47: Writing JavaScript that doesn't suck

Remember to use eventDelegationQuote from http://dev.opera.com/articles/view/efficient-javascript/?page=all

PerformancePerformance

Reflows

“whenever the DOM tree is manipulated, whenever a style is changed that affects the layout, whenever the className property of an element is changed, or whenever the browser window size is changed...

In many cases, they are equivalent to laying out the entire page again.”

Page 48: Writing JavaScript that doesn't suck

taken by Drew McLellan - http://www.flickr.com/photos/drewm/

Don’t forget your accessibility

Page 49: Writing JavaScript that doesn't suck

Don’t forget your accessibility

Don’t forget your focus (and blur)

Page 50: Writing JavaScript that doesn't suck

If you use .bind (opposed to .click) you can include multiple events

Don’t forget your accessibility

$(‘#foo’).bind(‘mouseenter focus’, function(e) {code goes here

});

$(‘#foo’).bind(‘mouseleave blur’, function(e) {code goes here

});

Page 51: Writing JavaScript that doesn't suck

Invalid mark-up is still invalid mark-up even when inserted via JS

Don’t forget your accessibility

Page 52: Writing JavaScript that doesn't suck

Remember to update the screenreader buffer

Don’t forget your accessibility

Page 53: Writing JavaScript that doesn't suck

The old(ish) way

Don’t forget your accessibility

1. Update the value of a hidden input field2. Ensure that you have a tabIndex value of -1 on the element that you’ve altered3. .focus() on the newly inserted content

Page 54: Writing JavaScript that doesn't suck

The new(ish) way - ARIA live regions

Don’t forget your accessibility

“Live region markup allows web page authors to specify when and how live changes to specific areas of a web page should be spoken or shown on a Braille display by a screen reader.”

Read more at https://developer.mozilla.org/en/AJAX/WAI_ARIA_Live_Regions

Page 55: Writing JavaScript that doesn't suck

The new(ish) way - ARIA live regionsRead more at https://developer.mozilla.org/en/AJAX/WAI_ARIA_Live_Regions

Don’t forget your accessibility

aria-live - sets the frequency of updates to AT

aria-controls - assosiates a control with an area. All actions on that control are announced by AT

aria-relevant - states what changes to the live region are to be announced to AT

Page 56: Writing JavaScript that doesn't suck

PerformanceDon’t forget your ‘edge cases’

Page 57: Writing JavaScript that doesn't suck

Remember to use eventDelegationIf things can go wrong then normally will

Don’t forget your ‘edge cases’

Page 58: Writing JavaScript that doesn't suck

Don’t forget your ‘edge cases’

Remember to code for when the server doesn’t return a value - it might be down or the app might be broken.

The server might take longer to reply than expected and cause a timeout meaning an empty return value.

If things can go wrong then normally will

Page 59: Writing JavaScript that doesn't suck

Remember to use eventDelegation$.ajax to the rescue

Don’t forget your ‘edge cases’

$.ajax is the backbone to all jQuery AJAX methods like $.getScript or $.getJSON and allows for much greater flexibility.

$.ajax({ url : “foo.php”, dataType : “json”, success : function(data) { gets sent the JSON response }, error : function() { gets sent the error type and text }, timeout : 1000});

Page 60: Writing JavaScript that doesn't suck

Remember to use eventDelegationMore information on the HTML5shiv at http://code.google.com/p/html5shiv/

Beware the HTML5 shiv

Don’t forget your ‘edge cases’

ALL current versions of IE can’t apply styles to the new HTML5 elements without the use of JavaScript.

Page 61: Writing JavaScript that doesn't suck

Remember to use eventDelegationBeware the HTML5 shiv

Don’t forget your ‘edge cases’

Lots of clever people recommend the use of Remy Sharps HTML5shiv to force IE into rendering these elements after it was found that creating empty pointers to them with JavaScript makes them styleable.

More information on the HTML5shiv at http://code.google.com/p/html5shiv/

Page 62: Writing JavaScript that doesn't suck

Remember to use eventDelegationBeware the HTML5 shiv

Don’t forget your ‘edge cases’

So JS is being used to ensure CSS works.

More information on the HTML5shiv at http://code.google.com/p/html5shiv/

Page 63: Writing JavaScript that doesn't suck

Remember to use eventDelegationFail?

Don’t forget your ‘edge cases’

Page 64: Writing JavaScript that doesn't suck

Remember to use eventDelegationA safer way

Don’t forget your ‘edge cases’

<div class=”section”> <section> </section></div>

You can now apply CSS to .section and be safe in the knowledge that they will always be applied.

Page 65: Writing JavaScript that doesn't suck

Remember to use eventDelegationClients wouldn’t like their site looking like this...

Don’t forget your ‘edge cases’

Page 66: Writing JavaScript that doesn't suck

Questions?

Page 67: Writing JavaScript that doesn't suck

Remember to use eventDelegationCheers!Taken by Mark Klotz - http://www.flickr.com/photos/markklotz/