<table cellpadding="0" cellspacing="0" border="0"> <tr> <td> <img src="link1.jpg" onmouseover="this.src='link1_over.jpg'" onmouseout="this.src='link1.jpg'"> </td> <td> <blink> <a href="javascript:void(0)" onclick="alert('Are you sure.')"> Click Here </a> </blink> </td> </tr> </table>
Confession: I used to write code like this on my IBM Aptiva while watching the Fresh Prince of Bel Air.
<script type="text/javascript" > function OnMouseOver(image, newSrc){ image.src = newSrc; } var ele = document.getElementById( 'myImage' ); if(document.attachEvent){ ele.attachEvent( 'click', ...); } else{ ele.addEventListener( 'click', ...); } </script>
<script src="da.js"></script> <script src="bears.js"></script> <script src="still.js"></script> <script src="suck.js"></script> <script src="so.js"></script> <script src="do.js"></script> <script src="the.js"></script> <script src="cubs.js"></script> </body> </html>
Then some hot shot designer who is a Bears fan edits your page...
<script src="still.js"></script> <!--oops this relied on the bears.js!--> <script src="suck.js"></script> <!--and this relied on still.js working--> <script src="the.js"></script> <script src="bears.js"></script>
And breaks EVERYTHING!
head.js("/path/to/jquery.js", "jquery.plugin.js", "/js/site.js");
$LAB.script("/path/to/jquery.js") .script("jquery.plugin.js").wait() .script("/js/site.js");
<!DOCTYPE html> <html> <head> <title>Awesome Stuff</title> <script data-main="scripts/main.js" src="scripts/require.js"> </script> </head> <body> ... </body> </html>
"The Asynchronous Module Definition (**AMD**) API specifies a mechanism for defining modules such that the module and its dependencies can be asynchronously loaded. This is particularly well suited for the browser environment where synchronous loading of modules incurs performance, usability, debugging, and cross-domain access problems. "
define( < id, > < [ dependencies ], > factory );
define( function( ){ return {}; } );
define( 'navView', [ 'jquery', 'underscore', 'backbone', 'models/user' ], function( $, _, Backbone, user ){ var NavView = Backbone.View.extend( { ... } ); return NavView; } );
The more modules you write, the better you'll become at determining what belongs in a module.
$( function(){ $( '#addEvent' ).on( 'click', function(){ //add a event }); $( '#events' ).on( 'click', '.viewEvent', function(){ //show the event }) .on( 'click', 'delete', function(){ //delete the event }); function validateEntry(){ //validate } });
define( 'calendar', function(){ var calendar = { addEvent : function(){ }, viewEvent : function(){ }, deleteEvent : function(){ }, validateEvent : function(){ } }; return { addEvent : calendar.addEvent, editEvent : calendar.editEvent, deleteEvent : calendar.deleteEvent }; });
require( [ 'calendar', function( cal ){ $( '#addEvent' ).on( 'click', cal.addEvent ); $( '#events' ) .on( 'click', '.viewEvent', cal.viewEvent) .on( 'click', 'delete', cal.deleteEvent ); } );
<script data-main="main.js" src="require.js"></script>
The data-main
attribute tells require to run the main.js to initialize the application.
require( [ 'app' ], function( app ){ app.init( ); } );
The require
function is used as a shortcut by RequireJS when a script has no exports. The AMD spec defines that the require function is optional for an AMD loader to implement.
app.js can have its own dependencies that will be resolved when it is included into main script.
require.config( { baseUrl : '', paths : { 'jquery', 'vendor/jquery-1.9.1.js'}, shim: { ... }, //added in RequireJS 2.1 config : { version : '0.9.1'}, deps : [ 'main' ] } );
To see all config options go to the require website: requirejs.org
index.html
<script data-main="config.js" src="require.js"></script>
config.js
require.config( { deps : [ 'main' ], ... } );
require.config({ paths:{ 'jquery': 'http://ajax.googleapis.com/.../jquery.min.js' } });
paths : { underscore : 'vendor/underscore', backbone : 'vendor/backbone' }, shim : { underscore : { exports : 'underscore' }, backbone : { deps : [ 'underscore', 'jquery' ], exports : 'Backbone' } }
paths : { jquery : 'vendor/jquery-1.9.1', 'jquery.validation' : 'vendor/jquery.validate.js', }, shim : { 'jquery.validation' : { deps : [ 'jquery' ], exports : 'jQuery.fn.validate' //checks of module is loaded } }
From the Lo-Dash source code:
if (typeof define == 'function' && typeof define.amd == 'object' && define.amd) { window._ = lodash; define(function() { return lodash; }); }
To use a plugin just add the plugin source file to the base directory of your application.
require( [ 'text!myViewTemplate.html' ], function( template ){ ... } });
Note the use of the !
, this is the syntax for loading a plugin.
define( 'userModel' , [ 'underscore', 'backbone' ], function(){ ... } ); define( 'userView' , [ 'userModel', 'underscore', 'backbone' ], function(){ ... } );
define( 'userModel' , [ 'underscore', 'backbone' ], function(){ ... } );
define( 'userView' , [ 'userModel', 'underscore', 'backbone' ], function(){ ... } );
views/appView.js
define( 'appView', [], function(){ } );
config.js
{ paths : { 'appView' : 'views/AppView' } }
appView.js
define( 'app-view', [], function(){ } );
config.js
{ paths : { 'app-view' : 'appView' } }
One module has a dependency on a module that has a dependency on it.
define( 'a', [ 'b' ], function(){ ... } );
define('b', [ 'a' ], function(){ ... } );
Node is the preferred environment in a CLI
({ baseUrl : 'js', out : 'main-min.js' paths : { } shim : { } name : 'main' // optimize : 'uglify' })
node r.js -o build.js
node r.js -o baseUrl=. name=main out=main-built.js
In the CLI dots are viewed as property seperators!
Page 1
<!DOCTYPE html> <html> <head> <title>Page 1</title> <script data-main="js/page1" src="js/lib/require.js"></script> </head> <body> <a href="page2.html">Go to Page 2</a> </body> </html>
//Load common code that includes config, then load the app logic for this page. require(['./common'], function (common) { require(['app/main1']); });
Page 2
<!DOCTYPE html> <html> <head> <title>Page 2</title> <script data-main="js/page2" src="js/lib/require.js"></script> </head> <body> <a href="page1.html">Go to Page 1</a> </body> </html>
//Load common code that includes config, then load the app logic for this page. require(['./common'], function (common) { require(['app/main2']); });
common.js
requirejs.config({ baseUrl: 'js/lib', paths: { app: '../app' } });
({ modules: [ //First set up the common build layer. { name: '../common', include: ['jquery', 'app/controller/Base', 'app/model/Base'] }, { name: '../page1', include: ['app/main1'], exclude: ['../common'] }, { name: '../page2', include: ['app/main2'], exclude: ['../common'] } ] })
Why AMD is Not the Answer by Tom Dale, one of the Ember.js creators.
3 new keywords
module
import
export
module person{ var name = ''; //private export function sayHello(){ return 'Hello, ' + name; } }
module carFactory{ export var ford = { make : 'Ford' }; export var chevy = { make : 'Chevrolet' }; }
module fusion{ import ford from carFactory; var model = 'Fusion'; export function getFullName(){ return ford.make + ' ' + model; } }
Project home page: https://code.google.com/p/traceur-compiler/
Online Compiler: http://traceur-compiler.googlecode.com/git/demo/repl.html
Playing with Harmony Modules and Traceur: http://blog.bittersweetryan.com/2013/02/playing-with-ecmascriptharmony-modules.html
/
#