A. 加速包js怎麼實現
基於 AngularJS 的拖拽指令
支持 GPU 加速
支持邊界限制
支持設置拖拽把柄
移動端與 PC 端通用
使用
支持使用 script 標簽或者 webpack、requirejs、seajs 調用:
script
調用
script src="lib/angular.js"></script>
<script src="dist/angular-drag.js"></script>
<script>
var app = angular.mole('app', ['angular-drag']);
</script>
webpack
安裝
npm install angular-drag
調用
require('angular-drag');
var app = angular.mole('app', ['angular-drag']);
angular-drag 依賴 angular 與 jquery 兩個全局模塊
指令
drag 被拖拽的元素
drag-handle 觸發拖拽的把柄(可選)
示例
簡單的可拖拽元素
<遲睜侍早橘div drag class="example">
hello world
</div>
自定義拖拽的把柄
<div drag class="example">
<碼吵div drag-handle></div>
<p>hello world</p>
</div>
B. seajs和requiejs的區別,和用gulp打包方法
從demo.html 引入一個入口c.js, c.js require-b.js , b.js require - a.js
代碼如下:
c mole
[html] view plain print?
define(function(require, exports, mole) {
console.log("hello mole c");
require('b');
console.log("c finished");
});
b mole
[html] view plain print?
define(function(require, exports, mole) {
console.log("hello mole b")
var a = require('a');
console.log("b finished")
});
a mole
[html] view plain print?
define(function() {
console.log("hello mole a")
});
requriejs 的 html代碼:
[html] view plain print?
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>seajs和requirejs的區別</title>
<script src="require.min.js" data-main="c.js"></script>
</head>
<body>
</body>
</html>
執行結果:
ello mole aa.js:2
hello mole bb.js:2
b finishedb.js:4
hello mole cc.js:3
c finishedc.js:7
seajs的html代碼:
[html] view plain print?
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>seajs和requirejs的區別</title>
<script src="sea.2.3.js"></script>
<script>
seajs.use('./c');
</script>
</head>
<body>
</body>
</html>
執行結果:
hello mole cc.js:3
hello mole bb.js:2
hello mole aa.js:2
b finishedb.js:4
c finishedc.js:7
所以總結:
seajs是從上到下執行,
requriejs是把其中require的js全部載入完了,再往下執行。·
2、依賴的載入有所不同
在define中 requriejs載入了依賴就執行;而seajs在define中只是載入不會執行(如果要執行,需要用require()方法)
案例代碼:
c.js模塊
[html] view plain print?
define(['b'],function(require,exports,mole){
console.log("hello mole c");
console.log("c finished");
});
b.js模塊
[html] view plain print?
define(['a'],function(require,exports,mole) {
console.log("hello mole b")
console.log("b finished")
});
a.js模塊
[html] view plain print?
define(['b'],function(require,exports,mole) {
console.log("hello mole a")
});
seajs和requirejs的 html代碼 和 1 中一樣
執行結果:
seajs執行結果:
hello mole cc.js:2
c finishedc.js:4
requiresj的執行結果:
ello mole aa.js:2
hello mole bb.js:2
b finishedb.js:4
hello mole cc.js:2
c finishedc.js:4
總結: 在define書寫中A:requirejs 載入了就執行,所以requirejs是預執行(在define中預先執行所有require依賴的js),RequireJS的做法是並行載入所有依賴的模塊, 並完成解析後, 再開始執行其他代碼, 因此執行結果只會"停頓"1次, 完成整個過程是會比SeaJS要快. 預執行
B:seajs只是純粹的載入依賴的文件,不執行就連console都不執行就是純粹的「載入」,SeaJS一樣是並行載入所有依賴的模塊, 但不會立即執行模塊, 等到真正需要(require)的時候才開始解析,
這里耗費了時間, 因為這個特例中的模塊巨大, 因此造成"停頓"2次的現象, 這就是我所說的SeaJS中的"懶執行".
在2的基礎上 c.js代碼為
[html] view plain print?
define(function(require,exports,mole){
require('b');
require('a');
console.log("hello mole c");
console.log("c finished");
});
執行結果都是一樣
hello mole bb.js:2
b finishedb.js:4
hello mole aa.js:2
hello mole cc.js:4
c finishedc.js:6
3、取別名時requirejs默認舍掉.js的後綴
4、 打包方法
gulp 打包seajs
requirejs 打包
C. 請教seajs 的define參數 的問題
開發階段不推薦define的參數傳入三個,只需給定後面的factory即可,發布時通過構建工版具提取壓權縮模塊,會自動加上idhe依賴數組(即第二個參數),這樣seajs能夠更快的定位本身這個模塊和它依賴的模塊。
順便提一下,第二個參數,如果顯示傳入了,那麼seajs就不會再通過正則去掃描factory.toString(),直接根據這個參數去載入依賴模塊,如果為[]即表示無依賴。
D. requirejs和seajs的區別
SeaJS對模塊的態度是懶執行, 而RequireJS對模塊的態度是預執行
如下模塊通過SeaJS/RequireJS來載入, 執行結果會是怎樣?
define(function(require, exports, mole) {
console.log('require mole: main');
var mod1 = require('./mod1');
mod1.hello();
var mod2 = require('./mod2');
mod2.hello();
return {
hello: function() {
console.log('hello main');
}
};
});
先試試SeaJS的執行結果
require mole: main
require mole: mod1
hello mod1
require mole: mod2
hello mod2
hello main
E. angularJS關於依賴和模塊與amd/cmd的區別,分享下結合使用示例
雙向綁定,可測試性的代碼結構,模型視圖分離的一個前端MV*框架
其中angular也提供了模型的概念和依賴管理,不過這個依賴都是要在js對象都已經定義的前提下,沒有像amd/cmd提供按需載入。
我個人比較喜歡cmd(seajs),它對頂級作用域window的使用約束較多,全局對象和方法少,缺點就是很多原生庫,都需要手工wrap下。
angular定義的controller一般都是全局的,我想用seajs來管理angular的代碼和依賴,下面是一起使用的示例,有類似需求的童鞋可以參考下:
java">//fileng_mole2.js
define(function(require){
varLog=require('log');
return{
init:function(){
Log.w('Loadangularmole:m2');
varag=window.angular;
if(!ag){
Log.w('Errorwhenloadangularmole:m2:noangular');
return;
}
varm2=ag.mole('m2',[]);
m2.filter('greet',function(){
returnfunction(name){
return'Hello,'+name+'!';
};
});
}
};
});
//fileng_mole1.js
define(function(require){
require('mole/demo/ng_mole2').init();
varLog=require('log');
return{
init:function(){
Log.w('Loadangularmole:m1');
varag=window.angular;
if(!ag){
Log.w('Errorwhenloadangularmole:m1:noangular');
return;
}
varm1=ag.mole('m1',['m2']);
m1.directive('testDateFormat',function(){
returnfunction(scope,el,attrs,ctrl){
varformat='yyyy-MM-dd';
varupdateTime=function(){
el.text(newDate().format(format));
};
//watchscope.formatinctrl
scope.$watch('format',function(value){
format=value;
updateTime();
});
updateTime();
}
});
}
};
});
//filedemo/ng1.js
//初始化頁面
define(function(require){
varLog=require('log');
require('mole/demo/ng_mole1').init();
varagAdaptor=require('x/x.ex.angular');
return{
initPage:function(from,pageInfo,params){
varTestCtrl=function($scope){
$scope.format='yyyy/MM/dd';
};
window.TestCtrl=TestCtrl;
agAdaptor.init(['m1'],'TestCtrl','ngContext');
},
mp:''
};
});
//filex/x.ex.angular.js
//angularbootstrap適配——在bootstrap之前動態修改下dom
define(function(require){
var$=require('jquery');
varLog=require('log');
return{
init:function(moles,ctrlName,contextId){
if(!window.angular){
Log.w('Noangluardefined!','WARN');
return;
}
var_context=$('#'+contextId);
this.initCtrl(_context,ctrlName);
this.initModel(_context);
this.bootstrapAngular(moles);
},
//把ng-controller補上
initCtrl:function(_context,ctrlName){
if(ctrlName)
_context.attr('ng-controller',ctrlName);
},
//根據name把ng-model補上
initModel:function(_context){
_context.find('[name^=f_]').each(function(){
var_el=$(this);
varname=_el.attr('name');
varmodelName=name.split('_').remove(0).join('.');
_el.attr('ng-model',modelName);
});
},
bootstrapAngular:function(moles){
window.angular.bootstrap(document,moles);
}
};
});
<divclass="m_10">
<h3>Angular——WorkwithSeaJS</h3>
<divid="ngContext">
Dateformat:<inputng-model="format">
<br/>
Currenttimeis:<spantest-date-format=""></span>
</div>
</div>
seajs.use('mole/demo/ng1',function(IPage){
IPage.initPage();
});
F. GitHub 上有哪些值得推薦的開源電子書
語言無關類
操作系統
鳥哥的Linux私房菜 (簡體)
Linux 系統高級編程
The Linux Command Line (中英文版)
Linux 設備驅動 (第三版)
深入分析Linux內核源碼
UNIX TOOLBOX
Docker中文指南
Docker —— 從入門到實踐
FreeRADIUS新手入門
Mac 開發配置手冊
FreeBSD 使用手冊
Linux 命令行(中文版)
一步步搭建物聯網系統
Nginx開發從入門到精通 (淘寶團隊出品)
Git教程 (本文由 @廖雪峰 創作,如果覺得本教程對您有幫助,可以去 iTunes 購買)
git – 簡易指南
猴子都能懂的GIT入門
Git 參考手冊
Pro Git
Git Magic
GotGitHub
Git Community Book 中文版
Mercurial 使用教程
HgInit (中文版)
沉浸式學 Git
Git-Cheat-Sheet (感謝 @flyhigher139 翻譯了中文版)
GitHub秘籍
NoSQL資料庫筆談 (PDF)
Redis 設計與實現
Redis 命令參考
帶有詳細注釋的 Redis 3.0 代碼
帶有詳細注釋的 Redis 2.6 代碼
The Little MongoDB Book
The Little Redis Book
Neo4j 簡體中文手冊 v1.8
Neo4j .rb 中文資源
MySQL索引背後的數據結構及演算法原理
持續集成(第二版) (譯言網)
讓開發自動化系列專欄
追求代碼質量
selenium 中文文檔
Joel談軟體
約耳談軟體(Joel on Software)
關於瀏覽器和網路的 20 項須知
前端知識體系
瀏覽器開發工具的秘密
Chrome 開發者工具中文手冊
Chrome擴展開發文檔
Grunt中文文檔
移動Web前端知識庫
正則表達式30分鍾入門教程
前端開發體系建設日記
移動前端開發收藏夾
JSON風格指南
HTTP 介面設計指北
前端資源分享(一)
前端資源分享(二)
前端代碼規范 及 最佳實踐
w3school教程整理
大數據/數據挖掘/推薦系統/機器學習相關資源
程序員編程藝術
每個程序員都應該了解的內存知識(譯)【第一部分】
取悅的工序:如何理解游戲 (豆瓣閱讀,免費書籍)
OpenWrt智能、自動、透明翻牆路由器教程
awk程序設計語言
C++ 並發編程指南 (@傅海平ICT)
Linux C編程一站式學習 (宋勁杉, 北京亞嵌教育研究中心)
CGDB中文手冊
100個gdb小技巧
100個gcc小技巧
ZMQ 指南
How to Think Like a Computer Scientist (中英文版)
跟我一起寫Makefile(PDF)
GNU make中文手冊
GNU make 指南
Google C++ 風格指南
C/C++ Primer (by @andycai)
簡單易懂的C魔法
Cmake 實踐 (PDF版)
C++ FAQ LITE(中文版)
C++ Primer 5th Answers
學習CSS布局
通用 CSS 筆記、建議與指導
CSS參考手冊
Emmet 文檔
前端代碼規范 (騰訊alloyteam團隊)
Dart 語言導覽
Fortran77和90/95編程入門
實時 Java 系列
Apache Shiro 用戶指南
使用 Eclipse 和 Java SE 6 創建獨立 Web Services 應用程序
第 1 部分: Web Services 服務端應用程序
第 2 部分: Web 服務客戶端應用程序
JavaServer Faces 1.2 入門
第 1 部分: 構建基本應用程序
第 2 部分: JSF 生命周期、轉換、檢驗和階段監聽器
用 Eclipse Europa 進行 Web 開發
第 1 部分: Eclipse Java EE
第 2 部分: PHP 開發工具
第 3 部分: Ruby Development Toolkit 和 RadRails
使用 JavaServer Faces 構建 Apache Geronimo 應用程序
第 1 部分: 使用 Eclipse 和 Apache MyFaces Core 構建基本的應用程序
第 2 部分: 在 JavaServer Faces 中使用 Tomahawk
第 3 部分: 使用 ajax4jsf 添加 Ajax 功能
第 4 部分: 使用 Apache Trinidad 組件擴展 JSF
第 5 部分: 將 JSF 應用程序與 Spring 集成
Apache Geronimo 和 Spring 框架
第 1 部分: 開發方法學
第 2 部分: 構建第一個應用程序
第 3 部分: 集成 DAO 與 ORM
第 4 部分: 混合使用 Spring AOP 和 Spring Web Flow
第 5 部分: Spring MVC
第 6 部分: Spring MVC:使用 Web 視圖技術
終極 mashup —— Web 服務和語義 Web
第 1 部分: 使用與組合 Web 服務
第 2 部分: 管理 Mashup 數據緩存
第 3 部分: 理解 RDF 和 RDFs
第 4 部分: 創建本體
第 5 部分: 切換 Web 服務
Jersey 2.x 用戶指南
MyBatis中文文檔
Google JavaScript 代碼風格指南
Airbnb JavaScript 規范
JavaScript 標准參考教程(alpha)
Javascript編程指南 (源碼)
javascript 的 12 個怪癖
JavaScript 秘密花園
JavaScript核心概念及實踐 (PDF) (此書已由人民郵電出版社出版發行,但作者依然免費提供PDF版本,希望開發者們去購買,支持作者)
《JavaScript 模式》翻譯,此書中文版有售,但是紙質書翻譯的還沒有這個版本翻譯的好
命名函數表達式探秘 (注:原文由為之漫筆翻譯,原始地址無法打開,所以此處地址為我博客上的備份)
學用 JavaScript 設計模式 (開源中國)
深入理解JavaScript系列
ECMAScript 6 入門 (作者:阮一峰)
jQuery
jQuery 解構
簡單易懂的JQuery魔法
How to write jQuery plugin
Node.js
Node入門
七天學會NodeJS
Nodejs Wiki Book (繁體中文)
express.js 中文文檔
koa 中文文檔
使用 Express + MongoDB 搭建多人博客
Express框架
nodejs文檔
Node.js 包教不包會
Learn You The Node.js For Much Win! (中文版)
Node debug 三法三例
underscore.js
Underscore.js中文文檔
backbone.js
backbone.js入門教程 (PDF)
Backbone.js入門教程第二版
Developing Backbone.js Applications(中文版)
AngularJS
AngularJS最佳實踐和風格指南
AngularJS中譯本
AngularJS入門教程
構建自己的AngularJS
在Windows環境下用Yeoman構建AngularJS項目
zepto 簡明中文手冊
Sea.js
Hello Sea.js
CoffeeScript
CoffeeScript Cookbook
The Little Book on CoffeeScript中文版
ExtJS
Ext4.1.0 中文文檔
Chrome擴展及應用開發
JavaScript入門教程
PHP調試技術手冊(PDF)
XDebug 2中文手冊(譯) (CHM)
PHP之道
PHP 最佳實踐
PHP安全最佳實踐
深入理解PHP內核
PHP擴展開發及內核應用
CodeIgniter 用戶指南
Laravel4 中文文檔
Laravel 入門
Symfony2中文文檔 (未譯完)
Phalcon中文文檔(翻譯進行中)
YiiBook幾本Yii框架的在線教程
簡單易懂的PHP魔法
swoole文檔及入門教程
iOS開發60分鍾入門
iOS7人機界面指南
Google Objective-C Style Guide 中文版
iPhone 6 屏幕揭秘
Apple Watch開發初探
馬上著手開發 iOS 應用程序
網易斯坦福大學公開課:iOS 7應用開發字幕文件
Android Design(中文版)
Google Android官方培訓課程中文版
Android學習之路
小白的Python教程
簡明Python教程
零基礎學Python
Python 2.7 官方教程中文版
Python 3.3 官方教程中文版
深入 Python 3
PEP8 Python代碼風格規范
Google Python 風格指南 中文版
Python入門教程 (PDF)
Python的神奇方法指南
笨辦法學 Python (PDF版下載)
Django 文檔中文版
Django 最佳實踐
The Django Book 中文版
web.py 0.3 新手指南
Web.py Cookbook 簡體中文版
Dive Into Python 中文版
Bottle 文檔中文版 (需翻牆)
Flask 文檔中文版
Jinja2 文檔中文版
Werkzeug 文檔中文版
Flask之旅
Introction to Tornado 中文翻譯
Python自然語言處理中文版 (感謝陳濤同學的翻譯,也謝謝 @shwley 聯系了作者)
Python 繪圖庫 matplotlib 官方指南中文翻譯
Scrapy 0.25 文檔
ThinkPython
Ruby 風格指南
Rails 風格指南
笨方法學 Ruby
Ruby on Rails 指南
Ruby on Rails 實戰聖經
Ruby on Rails Tutorial 原書第 2 版 (本書網頁版免費提供,電子版以 PDF、EPub 和 Mobi 格式提供購買,僅售 9.9 美元)
編寫Ruby的C拓展
Ruby 源碼解讀
Shell腳本編程30分鍾入門
Go編程基礎
Go入門指南
學習Go語言 (PDF)
Go Web 編程 (此書已經出版,希望開發者們去購買,支持作者的創作)
Go實戰開發 (當我收錄此項目時,作者已經寫完第三章,如果讀完前面章節覺得有幫助,可以給作者捐贈,以鼓勵作者的繼續創作)
Network programming with Go 中文翻譯版本
實戰 Groovy 系列
一份其實很短的 LaTeX 入門文檔
一份不太簡短的 LATEX 2ε 介紹 (PDF版)
ANSI Common Lisp 中文翻譯版
Lua編程入門
Real World Haskell 中文版
R語言忍者秘笈
Scala課堂 (Twitter的Scala中文教程)
Effective Scala(Twitter的Scala最佳實踐的中文翻譯)
Scala指南
The Swift Programming Language 中文版
Modern Perl 中文版
Perl 程序員應該知道的事
笨辦法學Prolog
Vim中文文檔
笨方法學Vimscript 中譯本
Vim中文文檔
編譯原理(紫龍書)中文第2版習題答案
把《編程珠璣》讀薄
Effective C++讀書筆記
Golang 學習筆記、Python 學習筆記、C 學習筆記 (PDF)
Jsoup 學習筆記
學習筆記: Vim、Python、memcached
圖靈開放書翻譯計劃–C++、Python、Java等
蒂姆·奧萊利隨筆 (由譯言網翻譯,電子版免費)
Octave 入門 (PDF版)
SICP 解題集
精彩博客集合
正則表達式簡明參考
G. 請大神幫我解答一下這個函數。。。包括function中的兩個參數
jQuery插件開發的五種形態
插件的第一形態
面對這種情況,通常我們會通過定義function的方式來實現。
復制代碼代碼如下:
function pluginName($selector){
$.each($selector, function () {
$(this).css("background-color", "#ccc");
// to do something...
});
}
// pluginName(document.getElementsByClassName("demo"));
因為我談的是jQuery插件開發,那麼我現在把這段代碼擴展到jQuery上,代碼如下:
復制代碼代碼如下:
// IIFE(立即調用函數表達式); [參考http://suqing.iteye.com/blog/1981591/]
;(function ($) {
// 擴展這個方法到jQuery.
// $.extend() 是吧方法擴展到 $ 對象上,和 $.fn.extend 不同。 擴展到 $.fn.xxx 上後,
// 調用的時候就可以是 $(selector).xxx()
$.fn.extend({
// 插件名字
pluginName: function () {
// 遍歷匹配元素的集合
// 注意這里有個"return",作用是把處理後的對象返回,實現鏈式操作
return this.each(function () {
// 在這里編寫相應的代碼進行處理
});
}
});
// 傳遞jQuery到內層作用域去, 如果window,document用的多的話, 也可以在這里傳進去.
// })(jQuery, window, document, undefined);
})(jQuery, undefined);
// 調用方式 $(".selector").pluginName().otherMethod();
但是還差的遠,目前只解決了兩個問題
代碼相對獨立
鏈式操作
插件可配置
有可操作的方法,插件的生命周期可控制
配置可被緩存
可擴展
無沖突處理
事件代理,動態初始化
插件的第二形態
現在來給插件添加參數支持。代碼如下
復制代碼代碼如下:
;(function($){
$.fn.pluginName = function(options) {
// 合並參數,通過「extend」合並默認參數和自定義參數
var args = $.extend({}, $.fn.pluginName.defaults, options);
return this.each(function() {
console.log(args.text);
// to do something...
});
};
// 默認參數
$.fn.pluginName.defaults = {
text : "hello"
};
})(jQuery);
// $(".selector").pluginName({
// text : "hello world!"
// });
添加參數支持還比較容易些,又解決一問題
代碼相對獨立
鏈式操作
插件可配置
有可操作的方法,插件的生命周期可控制
配置可被緩存
可擴展
無沖突處理
事件代理,動態初始化
插件的第三形態
現在來添加方法的支持,我前面所提到的生命周期可控制,意思差不多,例如添加reInit,destory等方法來控制插件。
復制代碼代碼如下:
;(function($){
$.fn.pluginName = function (method) {
// 如果第一個參數是字元串, 就查找是否存在該方法, 找到就調用; 如果是object對象, 就調用init方法;.
if (methods[method]) {
// 如果存在該方法就調用該方法
// apply 是吧 obj.method(arg1, arg2, arg3) 轉換成 method(obj, [arg1, arg2, arg3]) 的過程.
// Array.prototype.slice.call(arguments, 1) 是把方法的參數轉換成數組.
return methods[method].apply(this, Array.prototype.slice.call(arguments, 1));
} else if (typeof method === 'object' || !method) {
// 如果傳進來的參數是"{...}", 就認為是初始化操作.
return methods.init.apply(this, arguments);
} else {
$.error('Method ' + method + ' does not exist on jQuery.pluginName');
}
};
// 不把方法擴展在 $.fn.pluginName 上. 在閉包內建個"methods"來保存方法, 類似共有方法.
var methods = {
/**
* 初始化方法
* @param _options
* @return {*}
*/
init : function (_options) {
return this.each(function () {
var $this = $(this);
var args = $.extend({}, $.fn.pluginName.defaults, _options);
// ...
})
},
publicMethod : function(){
private_methods.demoMethod();
}
};
// 私有方法
function private_methods = {
demoMethod : function(){}
}
// 默認參數
$.fn.pluginName.defaults = {
};
})(jQuery);
// 調用方式
// $("div").pluginName({...}); // 初始化
// $("div").pluginName("publicMethod"); // 調用方法
又解決一問題
代碼相對獨立
鏈式操作
插件可配置
有可操作的方法,插件的生命周期可控制
配置可被緩存
可擴展
無沖突處理
事件代理,動態初始化
插件的第四形態
第三形態的插件修改就已經可以應對大多數插件的需求了。精益求精嘛,繼續升級。
第四形態的插件是照幫司徒正美的《javascript框架設計》的代碼。加了點面向對象的知識。
復制代碼代碼如下:
(function ($) {
var Plugin = function (element, options) {
this.element = element;
this.options = options;
};
Plugin.prototype = {
create: function () {
console.log(this.element);
console.log(this.options);
}
};
$.fn.pluginName = function (options) {
// 合並參數
return this.each(function () {
// 在這里編寫相應的代碼進行處理
var ui = $._data(this, "pluginName");
// 如果該元素沒有初始化過(可能是新添加的元素), 就初始化它.
if (!ui) {
var opts = $.extend(true, {}, $.fn.pluginName.defaults, typeof options === "object" ? options : {});
ui = new Plugin(this, opts);
// 緩存插件
$._data(this, "pluginName", ui);
}
// 調用方法
if (typeof options === "string" && typeof ui[options] == "function") {
// 執行插件的方法
ui[options].apply(ui, args);
}
});
};
$.fn.pluginName.defaults = {};
})(jQuery);
// 調用的方式和之前一樣。
這里特別要提下緩存這個東西,插件用多了,覺的這個真的是好東西。
在傳統面向對象的插件開發中,至少會聲明個變數保存它,但是我到目前寫的jQuery插件中都沒有,用起來很麻煩。自從把初始化後的插件緩存起來後,方便了許多。通過代碼$("#target").data("pluginName")就可以取到對象了。 來看看還有什麼問題沒有解決
代碼相對獨立
鏈式操作
插件可配置
有可操作的方法,插件的生命周期可控制
配置可被緩存
可擴展
無沖突處理
事件代理,動態初始化
插件的第五形態
看了上面的代碼是否腦子有點暈了,如果是,休息片刻,稍後回來,下面的代碼更精彩。 最後一個方案算是比較全面的了。方案來自Bootstrap,下面代碼以 Bootstrap 的 button 插件為例.
復制代碼代碼如下:
!function ($) {
// ecma262v5 的新東西, 強制使用嚴謹的代碼編寫.
"use strict";
// BUTTON PUBLIC CLASS DEFINITION
// ==============================
var Button = function (element, options) {
this.$element = $(element);
this.options = $.extend({}, Button.DEFAULTS, options);
};
Button.DEFAULTS = {
loadingText: 'loading...'
};
Button.prototype.setState = function (state) {
// ...
};
Button.prototype.toggle = function () {
// ...
};
// BUTTON PLUGIN DEFINITION
// ========================
var old = $.fn.button; // 這里的 $.fn.button 有可能是之前已經有定義過的插件,在這里做無沖突處理使用。
$.fn.button = function (option) {
return this.each(function () {
var $this = $(this);
// 判斷是否初始化過的依據
var data = $this.data('bs.button');
var options = typeof option == 'object' && option;
// 如果沒有初始化過, 就初始化它
if (!data) $this.data('bs.button', (data = new Button(this, options)));
if (option == 'toggle') data.toggle();
else if (option) data.setState(option)
})
};
// ① 暴露類名, 可以通過這個為插件做自定義擴展
$.fn.button.Constructor = Button;
// 擴展的方式
// 設置 : $.fn.button.Constructor.newMethod = function(){}
// 使用 : $btn.button("newMethod");
// ② 無沖突處理
$.fn.button.noConflict = function () {
$.fn.button = old;
return this
};
// ③ 事件代理, 智能初始化
$(document).on('click.bs.button.data-api', '[data-toggle^=button]', function (e) {
var $btn = $(e.target);
// 查找要初始化的對象
if (!$btn.hasClass('btn')) $btn = $btn.closest('.btn');
// 直接調用方法, 如果沒有初始化, 內部會先進行初始化
$btn.button('toggle');
e.preventDefault();
});
}(jQuery);
來看看還有什麼問題沒有解決
代碼相對獨立
鏈式操作
插件可配置
有可操作的方法,插件的生命周期可控制
配置可被緩存
可擴展
無沖突處理
事件代理,動態初始化
補充
現在的插件都要求靈活性要高,比如希望插件可以同時適配jQuery和Zepto,又或者需要支持AMD或者CMD規范。
支持jQuery和Zepto
復制代碼代碼如下:
if (window.jQuery || window.Zepto) {
(function ($) {
// plugin code...
})(window.jQuery || window.Zepto);
}
中間件支持,node
復制代碼代碼如下:
if (typeof(mole) !== 'undefined')
{
mole.exports = pluginName;
}
requirejs(AMD) support
if (typeof define === 'function' && define.amd) {
define([], function () {
'use strict';
return pluginName;
});
}
seajs(CMD) support
if (typeof define === 'function') {
define([], function () {
'use strict';
return pluginName;
});
}
H. seajs和requiejs的區別,和用gulp打包方法
1、執爛返行順序不同
從demo.html 引入一個入口c.js, c.js require-b.js , b.js require - a.js
代碼如下:
c mole
[html] view plain print?
define(function(require, exports, mole) {
console.log("hello mole c");
require('b');
console.log("c finished");
});
b mole
[html] view plain print?
define(function(require, exports, mole) {
console.log("hello mole b")
var a = require('a');
console.log("b finished")
});
a mole
[html] view plain print?
define(function() {
console.log("hello mole a")
});
requriejs 的 html代碼:
[html] view plain print?
<!doctype html>
<html lang="仔晌en">
<head>
<meta charset="UTF-8">
<title>seajs和requirejs的區別</title>
<script src="require.min.js" data-main="c.js"></script>
</head>
<body>
</body>
</html>
執行結果:
ello mole aa.js:2
hello mole bb.js:2
b finishedb.js:4
hello mole cc.js:3
c finishedc.js:7
==============================================
seajs的html代碼:
[html] view plain print?
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>seajs和requirejs的區別</title>
<script src="sea.2.3.js"></script>
<script>
seajs.use('./c'飢戚飢);
</script>
</head>
<body>
</body>
</html>
執行結果:
hello mole cc.js:3
hello mole bb.js:2
hello mole aa.js:2
b finishedb.js:4
c finishedc.js:7
所以總結:
seajs是從上到下執行,
requriejs是把其中require的js全部載入完了,再往下執行。·
2、依賴的載入有所不同
在define中 requriejs載入了依賴就執行;而seajs在define中只是載入不會執行(如果要執行,需要用require()方法)
案例代碼:
c.js模塊
[html] view plain print?
define(['b'],function(require,exports,mole){
console.log("hello mole c");
console.log("c finished");
});
b.js模塊
[html] view plain print?
define(['a'],function(require,exports,mole) {
console.log("hello mole b")
console.log("b finished")
});
a.js模塊
[html] view plain print?
define(['b'],function(require,exports,mole) {
console.log("hello mole a")
});
seajs和requirejs的 html代碼 和 1 中一樣
執行結果:
seajs執行結果:
hello mole cc.js:2
c finishedc.js:4
requiresj的執行結果:
ello mole aa.js:2
hello mole bb.js:2
b finishedb.js:4
hello mole cc.js:2
c finishedc.js:4
總結: 在define書寫中A:requirejs 載入了就執行,所以requirejs是預執行(在define中預先執行所有require依賴的js),RequireJS的做法是並行載入所有依賴的模塊, 並完成解析後, 再開始執行其他代碼, 因此執行結果只會"停頓"1次, 完成整個過程是會比SeaJS要快. 預執行
B:seajs只是純粹的載入依賴的文件,不執行就連console都不執行就是純粹的「載入」,SeaJS一樣是並行載入所有依賴的模塊, 但不會立即執行模塊, 等到真正需要(require)的時候才開始解析,
這里耗費了時間, 因為這個特例中的模塊巨大, 因此造成"停頓"2次的現象, 這就是我所說的SeaJS中的"懶執行".
在2的基礎上 c.js代碼為
[html] view plain print?
define(function(require,exports,mole){
require('b');
require('a');
console.log("hello mole c");
console.log("c finished");
});
執行結果都是一樣
hello mole bb.js:2
b finishedb.js:4
hello mole aa.js:2
hello mole cc.js:4
c finishedc.js:6
3、取別名時requirejs默認舍掉.js的後綴
4、 打包方法
gulp 打包seajs
requirejs 打包
http://blog.csdn.net/kongjiea/article/details/48316049
I. seajs和requiejs的區別,和用gulp打包方法
1、執行順序不同
從demo.html 引入一個入口c.js, c.js require-b.js , b.js require - a.js
代碼如下:
c mole
[html] view plain print?
define(function(require, exports, mole) {
console.log("hello mole c");
require('b');
console.log("c finished");
});
b mole
[html] view plain print?
define(function(require, exports, mole) {
console.log("hello mole b")
var a = require('a');
console.log("b finished")
});
a mole
[html] view plain print?
define(function() {
console.log("hello mole a")
});
requriejs 的 html代碼:
[html] view plain print?
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>seajs和requirejs的區別</title>
<script src="require.min.js" data-main="c.js"></script>
</head>
<body>
</body>
</html>
執行結果:
ello mole aa.js:2
hello mole bb.js:2
b finishedb.js:4
hello mole cc.js:3
c finishedc.js:7
==============================================
seajs的html代碼:
[html] view plain print?
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>seajs和requirejs的區別</title>
<script src="sea.2.3.js"></script>
<script>
seajs.use('./c');
</script>
</head>
<body>
</body>
</html>
執行結果:
hello mole cc.js:3
hello mole bb.js:2
hello mole aa.js:2
b finishedb.js:4
c finishedc.js:7
所以總結:
seajs是從上到下執行,
requriejs是把其中require的js全部載入完了,再往下執行。·
2、依賴的載入有所不同
在define中 requriejs載入了依賴就執行;而seajs在define中只是載入不會執行(如果要執行,需要用require()方法)
案例代碼:
c.js模塊
[html] view plain print?
define(['b'],function(require,exports,mole){
console.log("hello mole c");
console.log("c finished");
});
b.js模塊
[html] view plain print?
define(['a'],function(require,exports,mole) {
console.log("hello mole b")
console.log("b finished")
});
a.js模塊
[html] view plain print?
define(['b'],function(require,exports,mole) {
console.log("hello mole a")
});
seajs和requirejs的 html代碼 和 1 中一樣
執行結果:
seajs執行結果:
hello mole cc.js:2
c finishedc.js:4
requiresj的執行結果:
ello mole aa.js:2
hello mole bb.js:2
b finishedb.js:4
hello mole cc.js:2
c finishedc.js:4
總結: 在define書寫中A:requirejs 載入了就執行,所以requirejs是預執行(在define中預先執行所有require依賴的js),RequireJS的做法是並行載入所有依賴的模塊, 並完成解析後, 再開始執行其他代碼, 因此執行結果只會"停頓"1次, 完成整個過程是會比SeaJS要快. 預執行
B:seajs只是純粹的載入依賴的文件,不執行就連console都不執行就是純粹的「載入」,SeaJS一樣是並行載入所有依賴的模塊, 但不會立即執行模塊, 等到真正需要(require)的時候才開始解析,
這里耗費了時間, 因為這個特例中的模塊巨大, 因此造成"停頓"2次的現象, 這就是我所說的SeaJS中的"懶執行".
在2的基礎上 c.js代碼為
[html] view plain print?
define(function(require,exports,mole){
require('b');
require('a');
console.log("hello mole c");
console.log("c finished");
});
執行結果都是一樣
hello mole bb.js:2
b finishedb.js:4
hello mole aa.js:2
hello mole cc.js:4
c finishedc.js:6
3、取別名時requirejs默認舍掉.js的後綴
4、 打包方法
gulp 打包seajs
requirejs 打包
http://blog.csdn.net/kongjiea/article/details/48316049
J. seajs2.3.0和spm3怎麼配合打包
開發一個組件的流程: 初始化組件 在本地磁碟新建文件夾,文件夾名稱為組件名稱,名稱要符合 [a-z\d-.],並以英文字母開頭,首選合適的英文單詞, 禁止使用駝峰 。避免組件名稱產生沖突。 下面以epay-mole1為例,說明組件初始化過程。 $ mkdir epay-mole1 $ cd epay-mole1 $ spm init Creating a spm package: [?] Package name: epay-mole1 [?] Version: 0.0.0 [?] Description: [?] Author: Initialize a spm package Succeccfully! 初始化完成後會生成一個骨架,在這個基礎上進行開發更方便。 epay-mole1 ├── examples 組件演示 │ └── index.md ├── HISTORY.md 版本更新說明 ├── index.js 組件的主要入口文件 ├── package.json 版本等元信息 ├── README.md 組件總體說明,包括功能描述、api文檔 └── tests 單元測試 └── index-spec.js 4.首先分析組件的依賴,比如需要 jquery。 可以使用 spm install 下載依賴。 $ spm install jquery --save 這樣 spm 會自動在 package.json 中添加依賴,你也可以手動添加並 install 。 "spm": { "dependencies": { "jquery": "1.7.2" } } 並且,所有依賴的模塊都會被下載到 spm_moles 下。 修改 index.js 進行開發 var $ = require('jquery') var epayMole1 = function(){ this.info = 'hello mole1' }; mole.exports = epayMole1 啟動本地服務進行調試。 $ spm doc 通過瀏覽器訪問 http://127.0.0.1:8000/ 本地調試 examples 也使用 md 編寫,這樣寫起來非常方便。 在 examples/index.md 添加實例化代碼,可以直接 use。 seajs.use('../index', function(Mole1) { var mole1 = new Mole1() console.log(mole1.info) }); 也可以用 require 來調用模塊。 var Mole1 = require('index'); 通過四個 "````" 所包裹的代碼不僅會顯示成代碼片段,也會插入 HTML 中進行實際運行,這樣你調試好代碼後,演示頁面的文檔也同時生成好了。 spm doc 支持 livereload,只要通過 spm doc 啟動服務,修改文件後都會自動構建。 修改組件元信息 修改 package.json 配置打包方式 "spm": { "main": "index.js" } 這樣 spm build 將打包 index.js 文件,並將這個文件中的本地依賴文件也打包進來。 接下來就可以開始打包,build 後會在 dist 目錄生成打包的文件和 -debug 文件。 $ spm build 發布組件 你的組件發布後可以很方便的被其他組件調用。通過 spm publish 命令將會把你的組件發布到伺服器上。 $ spm publish 發布組件文檔 $ spm doc publish