一、Code Organization Conceptes代码组织概念
http://requirejs.org/---------RequireJS管理和构建系统
1.Key Concepts关键概念
1)封装。封装成单元模块,避免全部卸载$(document).ready()里面
2)继承。使用继承技术避免重复代码
3)核心主要是DOM,但不是全部
4)函数功能应该低耦合
2.Encapsulate封装
第一步是将应用功能分为多个小功能模块
1)The Object Literal
// Using an object literal for a jQuery feature
var myFeature = {
init: function( settings ) {
myFeature.config = {
items: $( "#myFeature li" ),
container: $( "<div class='container'></div>" ),
urlBase: "/foo.php?item="
};
// Allow overriding the default config
$.extend( myFeature.config, settings );
myFeature.setup();
},
setup: function() {
myFeature.config.items
.each( myFeature.createContainer )
.click( myFeature.showItem );
},
createContainer: function() {
var item = $( this );
var container = myFeature.config.container
.clone()
.appendTo( item );
item.data( "container", container );
},
buildUrl: function() {
return myFeature.config.urlBase + myFeature.currentItem.attr( "id" );
},
showItem: function() {
myFeature.currentItem = $( this );
myFeature.getContent( myFeature.showContent );
},
getContent: function( callback ) {
var url = myFeature.buildUrl();
myFeature.currentItem.data( "container" ).load( url, callback );
},
showContent: function() {
myFeature.currentItem.data( "container" ).show();
myFeature.hideContent();
},
hideContent: function() {
myFeature.currentItem.siblings().each(function() {
$( this ).data( "container" ).hide();
});
}
};
$( document ).ready( myFeature.init );
2)The Module Pattern
// The module pattern
var feature = (function() {
// Private variables and functions
var privateThing = "secret";
var publicThing = "not secret";
var changePrivateThing = function() {
privateThing = "super secret";
};
var sayPrivateThing = function() {
console.log( privateThing );
changePrivateThing();
};
// Public API
return {
publicThing: publicThing,
sayPrivateThing: sayPrivateThing
};
})();
feature.publicThing; // "not secret"
// Logs "secret" and changes the value of privateThing
feature.sayPrivateThing();
3)使用jQuery pattern
// Using the module pattern for a jQuery feature
$( document ).ready(function() {
var feature = (function() {
var items = $( "#myFeature li" );
var container = $( "<div class='container'></div>" );
var currentItem = null;
var urlBase = "/foo.php?item=";
var createContainer = function() {
var item = $( this );
var _container = container.clone().appendTo( item );
item.data( "container", _container );
};
var buildUrl = function() {
return urlBase + currentItem.attr( "id" );
};
var showItem = function() {
currentItem = $( this );
getContent( showContent );
};
var showItemByIndex = function( idx ) {
$.proxy( showItem, items.get( idx ) );
};
var getContent = function( callback ) {
currentItem.data( "container" ).load( buildUrl(), callback );
};
var showContent = function() {
currentItem.data( "container" ).show();
hideContent();
};
var hideContent = function() {
currentItem.siblings().each(function() {
$( this ).data( "container" ).hide();
});
};
items.each( createContainer ).click( showItem );
return {
showItemByIndex: showItemByIndex
};
})();
feature.showItemByIndex( 0 );
});
二、Beware Anonymous Functions
使用对象来命名回调和处理,不然不好调试和替换等等。
// BAD 坏
$( document ).ready(function() {
$( "#magic" ).click(function( event ) {
$( "#yayeffects" ).slideUp(function() {
// ...
});
});
$( "#happiness" ).load( url + " #unicorns", function() {
// ...
});
});
// BETTER 好
var PI = {
onReady: function() {
$( "#magic" ).click( PI.candyMtn );
$( "#happiness" ).load( PI.url + " #unicorns", PI.unicornCb );
},
candyMtn: function( event ) {
$( "#yayeffects" ).slideUp( PI.slideCb );
},
slideCb: function() { ... },
unicornCb: function() { ... }
};
$( document ).ready( PI.onReady );
三、Keep Things DRY
// BAD
if ( eventfade.data( "currently" ) !== "showing" ) {
eventfade.stop();
}
if ( eventhover.data( "currently" ) !== "showing" ) {
eventhover.stop();
}
if ( spans.data( "currently" ) !== "showing" ) {
spans.stop();
}
// GOOD!!
var elems = [ eventfade, eventhover, spans ];
$.each( elems, function( i, elem ) {
if ( elem.data( "currently" ) !== "showing" ) {
elem.stop();
}
});