javascript and ui architecture best practices

43

Upload: siarhei-barysiuk

Post on 06-May-2015

12.796 views

Category:

Technology


3 download

DESCRIPTION

Day 5 of 7-days "JavaScript and Rich User Interfaces" training for my colleagues. It covers coding and design patterns.

TRANSCRIPT

Page 1: JavaScript and UI Architecture Best Practices
Page 2: JavaScript and UI Architecture Best Practices

JavaScript and UI ArchitectureBest Practices

Siarhei [email protected]

Page 3: JavaScript and UI Architecture Best Practices

Our roadmap

Page 4: JavaScript and UI Architecture Best Practices

Introduction: What will we cover today?

• Coding patterns JavaScript-specific best practices • Design patterns Language independent patterns, UI architecture

Page 5: JavaScript and UI Architecture Best Practices

Coding patterns

Page 6: JavaScript and UI Architecture Best Practices

Namespaces

Page 7: JavaScript and UI Architecture Best Practices

Tip of the day

“Global variables should be avoided in order to lower the possibility of variable naming collisions. “

Page 8: JavaScript and UI Architecture Best Practices

Namespaces: Defining namespace

//defining top-level packagevar MyApp = MyApp || {};

//defining package MyApp.string = MyApp.string || {};//defining packageMyApp.string.utils = { trim: function(str) { //code goes here }, reverse: function(str) { //code goes here }};

//defining package MyApp.dom = { addEventListener: function(element,

callback) { //code goes here }, removeEventListener: function(element, callback) { //code goes here }};

Page 9: JavaScript and UI Architecture Best Practices

Namespaces: Usage in code

MyApp.string.utils.reverse(...);MyApp.string.utils.trim(...);

MyApp.dom.addEventListener(...);MyApp.dom.removeEventListener(...);

Page 10: JavaScript and UI Architecture Best Practices

Namespaces: namespace() function

//defining top-level packagevar MyApp = MyApp || {};

//defines package structureMyApp.namespace = function(name) { if(name) { //some checks if name is valid var names = name.split("."); var current = MyApp; for(var i in names) { if(!current[names[i]]) { current[names[i]] = {}; } current = current[names[i]]; } return true; } return false;};

Page 11: JavaScript and UI Architecture Best Practices

Namespaces: Defining namespace

//defining top-level packagevar MyApp = MyApp || {};

//defining package MyApp.string = MyApp.string || {};//defining packageMyApp.string.utils = { trim: function(str) { //code goes here }, reverse: function(str) { //code goes here }};

//defining package MyApp.namespace("string.utils");//defining packageMyApp.string.utils.trim = function(str) { //code goes here console.log("trim"); };MyApp.string.utils.reverse = function(str) { //code goes here console.log("reverse"); };

Page 12: JavaScript and UI Architecture Best Practices

Questions?

Page 13: JavaScript and UI Architecture Best Practices

Init-time branching

Page 14: JavaScript and UI Architecture Best Practices

Tip of the day

“Branch some parts of the browser-specific code during initialization, when the script loads, rather than during runtime to avoid performance hit.”

Page 15: JavaScript and UI Architecture Best Practices

Init-time branching: Defining browser-specific methodsMyApp.namespace("dom");MyApp.dom.addListener = null;

//all major browsersif(typeof window.addEventListener === 'function') { MyApp.dom.addListener = function(el, type, fn) { el.addEventListener(type, fn, false); }; }//IEelse if(typeof document.attachEvent === 'function') { MyApp.dom.addListener = function(el, type, fn) { el.attachEvent('on' + type, fn); };}//older browserselse { MyApp.dom.addListener = function(el, type, fn) { el['on' + type] = fn; }; }

Page 16: JavaScript and UI Architecture Best Practices

Questions?

Page 17: JavaScript and UI Architecture Best Practices

Lazy definition

Page 18: JavaScript and UI Architecture Best Practices

Tip of the day

“The lazy definition pattern is very similar to the previous init-time branching pattern.

The difference is that the branching happens only when the function is called for the first time.”

Page 19: JavaScript and UI Architecture Best Practices

Lazy definition: Defining browser-specific methodsvar MyApp = MyApp || {};

MyApp.dom = { addListener: function(el, type, fn){ if (typeof el.addEventListener === 'function') { MyApp.dom.addListener = function(el, type, fn) { el.addEventListener(type, fn, false); }; } else if (typeof el.attachEvent === 'function'){ MyApp.dom.addListener = function(el, type, fn) { el.attachEvent('on' + type, fn); }; } else { MyApp.dom.addListener = function(el, type, fn) { el['on' + type] = fn; }; } MyApp.dom.addListener(el, type, fn); } };

Override function first time

Page 20: JavaScript and UI Architecture Best Practices

Questions?

Page 21: JavaScript and UI Architecture Best Practices

Configuration object

Page 22: JavaScript and UI Architecture Best Practices

Tip of the day

“Instead of having many parameters, you can use one parameter and make it an object.

The properties of the object are the actual parameters.”

Page 23: JavaScript and UI Architecture Best Practices

var MyApp = MyApp || {}; MyApp.namespace("dom"); MyApp.dom.Button = function(text, type) { //some code here}

Configuration object: Ordinary constructor

MyApp.dom.Button = function(text, type, color, border, font) { //some code here}

Page 24: JavaScript and UI Architecture Best Practices

Configuration object: Usage of configuration object

var MyApp = MyApp || {}; MyApp.namespace("dom"); MyApp.dom.Button = function(text, settings) { var type = settings.type || 'submit'; var font =settings.font ||'Verdana'; //..other props //some code here}

Page 25: JavaScript and UI Architecture Best Practices

Questions?

Page 26: JavaScript and UI Architecture Best Practices

Private properties and methods

Page 27: JavaScript and UI Architecture Best Practices

Tip of the day

“Use local variables and methods inside a constructor to achieve the “private” level of protection.

Use naming conventions _doInternalOperation to show that the function is private/protected.”

Page 28: JavaScript and UI Architecture Best Practices

var MyApp = MyApp || {}; MyApp.namespace("dom");

MyApp.dom.Button = function(text, settings) { //..process properties function setStyle(element, settings) { //setting style to element };

var button = //... //.. setStyle(button,settings); this.clone = function() { var clonedButton = //... //... setStyle(clonedButton, settings); } //some code here}

Private methods and properties: Private method

Page 29: JavaScript and UI Architecture Best Practices

Questions?

Page 30: JavaScript and UI Architecture Best Practices

Self-executing functions

Page 31: JavaScript and UI Architecture Best Practices

Tip of the day

“Self-executing functions are especially suitable for one-off initialization tasks performed when the script loads.”

Page 32: JavaScript and UI Architecture Best Practices

(function() { //code goes here})();

Self-executing functions: Usage

(function(){ // ... var jQuery = window.jQuery = window.$ = function( selector, context ) { // ... return new jQuery.fn.init( selector, context ); }; // ... jQuery.fn = jQuery.prototype = { init: function() { //... } };})();

Page 33: JavaScript and UI Architecture Best Practices

Questions?

Page 34: JavaScript and UI Architecture Best Practices

Chaining

Page 35: JavaScript and UI Architecture Best Practices

Tip of the day

“Pretty convenient way to call several related methods on one line as if the methods are the links in a chain.”

Page 36: JavaScript and UI Architecture Best Practices

var obj = new MyApp.dom.Element('span');

obj.setText('hello'); obj.setStyle('color', 'red'); obj.setStyle('font', 'Verdana');

document.body.appendChild(obj);

Chaining: Usage

var obj = new MyApp.dom.Element('span');

obj.setText('hello') .setStyle('color', 'red') .setStyle('font', 'Verdana'); document.body.appendChild(obj);

document.body.appendChild( new MyApp.dom.Element('span') .setText('hello') .setStyle('color', 'red') .setStyle('font', 'Verdana') );

Page 37: JavaScript and UI Architecture Best Practices

Questions?

Page 38: JavaScript and UI Architecture Best Practices

Design patterns

Page 39: JavaScript and UI Architecture Best Practices

Unobtrusive JavaScript

Page 40: JavaScript and UI Architecture Best Practices

Unobtrusive JavaScript: Separate JavaScript functionality

<a onclick="doSomething()" href="#">Click!</a>

<a href="backuplink.html" class="doSomething">Click!</a>

$('a.doSomething').click(function(){ // Do something here! alert('You did something, woo hoo!'); });

Page 41: JavaScript and UI Architecture Best Practices

Unobtrusive JavaScript: Never depend on JavaScript

<script type="text/javascript"> var now = new Date(); if(now.getHours() < 12) document.write('Good Morning!'); else document.write('Good Afternoon!');</script>

<p title="Good Day Message">Good Morning!</p>

var now = new Date();if(now.getHours() >= 12){ var goodDay = $('p[title="Good Day Message"]'); goodDay.text('Good Afternoon!');}

Page 42: JavaScript and UI Architecture Best Practices

Unobtrusive JavaScript: Never depend on JavaScript

<a href="javascript:window.open('page.html')">my page</a>

<a href="#" onclick="window.open('page.html')">my page</a>

<a href="page.html" onclick="window.open(this.href)">my page</a>

<a href="page.html" class="popup">my page</a>//some java script to open element with class ".popup" in a new window

Page 43: JavaScript and UI Architecture Best Practices

Questions?