一月份的時候,臨近放假,拿到一個需求,新增一個產品,我一個前端對一個java後端,兩個星期的開發時間。 由於大部分功能在別的產品都已經有了,基本都是簡單處理一下拿過來,再添加一下額外須要的功能,好比選擇出行國家等。前一天拿到文檔看了下,搞清楚以後,次日開工,基本一天就把功能作完了。這一天的大部分時間仍是花在-找代碼上。無他,實在是遺留的代碼 不是很清晰。javascript
由於系統比較舊,先後端也沒有分離,jsp的,代碼也很混亂,邏輯裏面還有不少奇怪的註釋,在這些上面作了不少無用功。 基本作好功能,聯調測試,經過以後基本就OK了。css
可是兩個周的時間才用了兩三天。還有十來天呢,怎麼辦呢,看着這些混亂的代碼,本着造福別人,也爲之後的方便,就想着,用模塊從新組織一下吧。由於去年有過這方面經驗,輕車熟路。因此,就有了後來的故事和今天的這篇文字。html
改造前的代碼大概是這個樣子的:前端
<link href="../mobileSinglePlatform/css/miuiall.css" type="text/css" rel="stylesheet"> <link href="../mobileSinglePlatform/css/miuitraffic.css" type="text/css" rel="stylesheet"> <link href="../mobileSinglePlatform/css/mobiscroll.core-2.5.2.css" rel="stylesheet" type="text/css" /> <script src="../mobileSinglePlatform/js/jquery-1.8.2.min.js" type="text/javascript"></script> <script type="text/javascript" src="https://res.wx.qq.com/open/js/jweixin-1.0.0.js"></script> <script src="../mobileSinglePlatform/js/common.js" type="text/javascript"></script> <script src="../mobileSinglePlatform/js/dateUtil.js" type="text/javascript"></script> <script src="../mobileSinglePlatform/js/ahsInsuranceForGroup_1.js" type="text/javascript"></script> <script src="../mobileSinglePlatform/js/mobiscroll.core-2.5.2.js" type="text/javascript"></script> <script src="../mobileSinglePlatform/js/mobiscroll.core-2.5.2-zh.js" type="text/javascript"></script> <script src="../mobileSinglePlatform/js/mobiscroll.datetime-2.5.1.js" type="text/javascript"></script> <script src="../mobileSinglePlatform/js/mobiscroll.datetime-2.5.1-zh.js" type="text/javascript"></script> <script src="../mobileSinglePlatform/js/jquery.form.js" type="text/javascript"></script> <script type="text/javascript" src="../mobileSinglePlatform/js/commonTools.js"></script> <script type="text/javascript" src="../mobileSinglePlatform/js/getOpenId.js"></script> <script type="text/javascript" src="../mobileSinglePlatform/js/wechatUtil.js"></script> <script src="//www.pingan.com/app_js/sdc/prd/sdc9_m.js"> </script> <script src="../mobileSinglePlatform/js/webtrends.js"></script> <script type="text/javascript"> initWebtrends(); </script> <c:if test="${not empty productDetail.specialPromise}"> <tr> <td colspan="2"> </td> </tr> <tr> <th width="60%" align="left">特別約定</th> <th width="40%" align="right"> </th> </tr> <tr> <td colspan="2"> <div id="specialInsurance" class="specialInsurance"> <div id="specialInsurancener"> <c:out value="${productDetail.specialPromise}"/> </div> </div> <div id="readmore" class="specialInsurance" style="margin-top:3%;"> </div> </td> </tr> </c:if> <c:choose> <c:when test="${not empty discountAmount}"> <tr> <td colspan="2"> <!--#=保費--> <div class="left fsize03 fwight" style="margin-top:20px;">標準保費 <del datetime="20150428"><font id="fontColor"><span id="amount"><c:out value="${AMOUNT }"/></span>元/人</font></del></div> </td> </tr> <tr> <td colspan="2"> <!--#=保費優惠價--> <div class="left fsize03 fwight" style="margin-top: 5px;color: #F00;padding: 5px 0px">優惠價 <span id="standardAmount"><c:out value="${discountAmount }"/></span>元/人</div> </td> </tr> </c:when>
很少貼代碼了,大概就是這個樣子的。這種狀況的緣由大概是:java
1.起初的頁面是後端人員寫的,沒有很好的組織各類資源。寫到必定數量以後,各類邏輯已經耦合在一塊兒,別的人接手以後,又不敢亂改,就按之前的作法複製粘貼,作好本身的那一塊。長此以往,頁面就愈來愈複雜,冗餘也愈來愈多,造成了一個惡性循環。node
2.網絡環境不容許。使用公司標配的聯想筆記本,標裝以後,收到公司安全策略的限制,不少技術網站沒法訪問,查資料有時候只能看百度快照,有些同事只好用手機或者自帶電腦來解決這個問題。至於 github,google,基本是不可能的。jquery
3.沒有代碼規範。基本每一個人都是按照本身的風格來,最後歸併以後的代碼就顯得很混亂。git
因爲不能使用腳手架自動化工具,這種情景要作模塊化,requireJs/seaJs 是比較好的選擇。去年用過requireJs,此次就用一下seaJs.github
因爲項目中的樣式文件實在太多太雜,時間上不容許我從新組織一遍,因此就只對邏輯代碼作了模塊化處理。web
要組織模塊,首先要弄清楚相應的規則。最好的方式固然是看 seajs文檔 了.
這裏也簡單介紹下幾個經常使用的功能。
// 頁面中包括的js <script src="./js/seajs/2.3.0/sea.js" id="seajsnode" ></script> <!-- 加上 seajsnode 值,可讓 sea.js 直接獲取到自身路徑,而不須要經過其餘機制去自動獲取。 這對性能和穩定性會有必定提高,推薦默認都加上。 --> <script src="./js/config-seajs.js" ></script> <!--配置項 --> <script type="text/javascript"> seajs.use('main'); /* seajs.use 理論上只用於加載啓動,不該該出如今 define 中的模塊代碼裏。 在模塊代碼裏須要異步加載其餘模塊時,推薦使用 require.async 方法。 */ </script>
再看一下配置信息:
seajs.config({ base:"./js/", paths: { //當目錄比較深,或須要跨目錄調用模塊時,可使用 paths 來簡化書寫。 "seajs": "seajs/2.3.0/sea.js" }, alias:{ // 設置別名,方便調用 , 當模塊標識很長時,可使用 alias 來簡化。 "jquery" : "lib/jquery/1.10.0/jquery.min.js", 'Hello':'mod/mod4.js', }, map: [ [".js",".js?1.0"] ], debug:true //值爲 true 時,加載器不會刪除動態插入的 script 標籤。插件也能夠根據 debug 配置,來決策 log 等信息的輸出。 });
而後是頁面入口:
//main.js /* define define(factory) define 接受 factory 參數,factory 能夠是一個函數,也能夠是一個對象或字符串。 factory 爲對象、字符串時,表示模塊的接口就是該對象、字符串。好比能夠以下定義一個 JSON 數據模塊: define({ "foo": "bar" }); 也能夠經過字符串定義模板模塊: define('I am a template. My name is {{name}}.'); factory 爲函數時,表示是模塊的構造方法。執行該構造方法,能夠獲得模塊向外提供的接口。factory 方法在執行時,默認會傳入三個參數:require、exports 和 module: define(function(require, exports, module) { // 模塊代碼 }); */ define(function (require, exports, module) { var $ = require('jquery'); console.log($); require('mod1'); var Hello = require('Hello'); Hello.init(); // other code... });
看一下模塊內的代碼:
//mod1.js define(function (require, exports, module) { console.log('mod1加載完畢'); });
//mod4.js define('Hello',function(require,exports, module) { var Hello = { sayHello:function(){ console.log('hello'); } } module.exports = Hello; });
打開頁面控制檯,就會看到輸出的信息:
說明咱們的模塊已經被成功的被加載了。
固然 實際的工做中還要用到各類插件,這就須要知道如何改造現有文件爲 CMD 模塊
這些在文檔中都能找到。
以上簡單介紹了使用seajs 組織模塊的方法。
固然,模塊寫完以後呢,咱們還須要相應的構建工具。
玉伯說:
若是使用 Sea.js,強烈推薦採用配套的構建工具來壓縮、合併代碼。若是不這麼作,可能會帶來很多額外的工做甚至隱患。
若是不合並代碼,也能運行,你會看到你的插件代碼都會以async的方式插入到頁面的頭部。並且須要你手動處理依賴關係,也產生了額外的請求,不是很友好。以下圖:
因此,爲了不意外的發生,也爲了減小請求數,應該合併模塊。
咱們來看一個實際的例子-支付寶的登錄頁面。
![clipboard.png]
很直觀的就能看到插模塊的合併,這個合併的工做就是構建工具的功勞了。
咱們也來實現一下。
先看效果吧,執行模塊合併以後,入口文件能夠是這樣的:
這樣就實現了模塊的打包合併。
我這裏使用了gulp來實現這一步, 代碼以下:
//seajs合併模式 gulp.task("seajs", function () { return merge( gulp.src(src + '/js/!(lib)/**/*.js', {base: src + '/js'}) .pipe(transport()) .pipe(concat({ base: src + '/js' })) .pipe(replace({ patterns: replace_patterns })) .pipe(gulp.dest(dist + '/js')), gulp.src([src + '/js/lib/**/*.js', src + '/js/common.js'], { base: src + '/js' }) .pipe(replace({ patterns: replace_patterns })) .pipe(gulp.dest(dist + '/js')) ); });
使用gulp提取模塊有其餘更詳細的教程,這裏提供一個我認爲比較好的:
那個支付寶的登錄頁 這裏給出完整代碼,給你們觀摩:
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <meta http-equiv="X-UA-Compatible" content="IE=edge, chrome=1"/> <meta name="renderer" content="webkit"/> <title>支付寶快捷收銀臺</title> <meta name="apple-mobile-web-app-capable" content="yes"/> <meta name="apple-mobile-web-app-status-bar-style" content="black"/> <meta name="format-detection" content="telephone=no,email=no"/> <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=0"/> <link rel="apple-touch-icon" href="https://i.alipayobjects.com/i/ecmng/png/201406/2qBuceUYiL.png" /> <link rel="apple-touch-icon-precomposed" href="https://i.alipayobjects.com/i/ecmng/png/201406/2qBuceUYiL.png" /> <!-- CMS:安全支付客戶端網關/common/tracker.vm開始:common/tracker.vm --> <!-- CMS:安全支付客戶端網關/common/tracker.vm結束:common/tracker.vm --><script charset="utf-8" src="https://as.alipayobjects.com:443/g/snake/h5cashier/1.0.5/h5cashier.js"></script> <link rel="stylesheet" type="text/css" href="https://as.alipayobjects.com:443/g/snake/h5cashier/1.0.5/h5cashier.css" media="all" /> <script charset="utf-8" id="seajsnode" src="https://a.alipayobjects.com:443/??seajs/seajs/2.2.0/sea.js,seajs/seajs-combo/1.0.0/seajs-combo.js"></script> <script> seajs.config({ alias: { '$': 'gallery/zepto/1.0.2/zepto', 'validator': 'arale/validator/0.9.7/validator', 'widget': 'arale/widget/1.1.1/widget', 'base': 'arale/base/1.1.1/base', 'class': 'arale/class/1.1.0/class', 'events': 'arale/events/1.1.0/events', 'wapcashier': 'mobileclientgw/wapcashier/1.1.7/wapcashier' }, vars: { locale: 'zh-cn' } }); </script> </head> <body> <div class="J-msg-mask am-msg-mask" style="display:none"></div> <div class="J-msg-box am-msg-box" style="display:none"> <div class="am-msg-box-content"> <p class="J-msg-text"></p> <button class="J-msg-cancel am-button am-button-blue" type="button">知道了</button> </div> </div> <div class="J-loading am-loading"><div class="am-loading-text">加載中...</div></div> <!-- CMS:安全支付客戶端網關/common/notice.vm開始:common/notice.vm --><!-- CMS:安全支付客戶端網關/common/notice.vm結束:common/notice.vm --> <!-- cashierLoginNew.vm --> <!-- v5_need_login_new --> <script>window.Tracker && Tracker.click('v5_need_login_new')</script> <header class="am-header"> <h1> <span class="title-main" data-title="登陸支付寶">登陸支付寶</span> </h1> <a href="#" class="J-back J-header-back am-header-reverse am-header-reverse-icon" seed="v5_need_login_new-back"><i class="icon icon-arrow-back"></i><span>返回</span></a> </header> <noscript><h1 style="color:red">您的瀏覽器不支持JavaScript,請更換瀏覽器或開啓JavaScript設置!</h1></noscript> <style> h5 { overflow: hidden; } .am-content h5.am-ft-mb-20 { margin-bottom: 20px; } </style> <div class="am-content"> <form id="cashier" action="https://mclient.alipay.com/h5/loginIdPwdLogin.htm?awid=RZ117V8UyX8dVXb9l8WaAkSdN6nF7kmobileclientgwRZ11" method="post"> <!-- 禁止瀏覽器自動填充帳戶名密碼 --> <input style="display:none" type="text" name="fakeusernameremembered"/> <input style="display:none" type="password" name="fakepasswordremembered"/> <!-- /禁止瀏覽器自動填充帳戶名密碼 --> <input type="hidden" name="_form_token" value="b63232f9568b71d0ad1425ca684e67f9b546a51c877e484f987868163c47e6f2RZ11"/> <input type="hidden" name="params" value="{"server_param":"c2hhcmVkX3RhaXI9dHJ1ZTtiaXpfdHlwZT1tZXJjaGFudDthY3Rpb249cGFyc2VyTG9nb25JZDs%3D","shared_tair":"true"}" /> <input type="hidden" name="session" value="RZ11Pu0jYCjXnsRvOUWIWJNRmBh2BamobilecashierRZ11" /> <input type="hidden" name="check_pay_pwd" value="true" /> <div class="am-list"> <div class="J-inputClear am-list-item am-list-item-form am-flexbox"> <label for="logon_id">帳戶 </label> <div class="am-flexbox-item"> <input id="logon_id" name="logon_id" type="text" maxlength="100" placeholder="支付寶帳戶" value="" autocomplete="off" autofocus="autofocus" /> </div> </div> <div class="J-inputClear am-list-item am-list-item-form am-flexbox"> <label for="pwd">密碼 </label> <div class="am-flexbox-item"> <input type="password" class="J-pwd" id="pwd_unencrypt" name="pwd_unencrypt" maxlength="100" placeholder="是支付密碼,不是登陸密碼" autocomplete="off" /> <input type="hidden" id="pwd" name="pwd" class="J-encryptpwd" /> </div> </div> </div> <div class="am-section"> <div class="am-ft-pb-10"> <button type="submit" class="am-button am-button-blue" seed="v5_need_login_new-submit">下一步</button> </div> <h5 class="am-ft-gray am-ft-mb-20"> <a class="fn-right" href="https://d.alipay.com/i/index.htm?pageSkin=skin-h5cashier&iframeSrc=alipays%3A%2F%2Fplatformapi%2FstartApp%3FappId%3D20000013%26pwdType%3DordinaryPassword" seed="v5_need_login_new-forget-pwd">忘記密碼</a> </h5> </div> </form> </div> <script type="text/javascript"> seajs.use(['$', 'wapcashier', 'validator', 'widget', 'base', 'class', 'events'],function($, wapcashier, Validator){ //刷新圖片校驗碼 var checkCode = $('.J-check-code'); checkCode.on('click',function(e){ var el = $(e.target); el.attr('src', el.attr('src') + '&s=' + Math.random()) }); //表單校驗 var validator = new Validator({ element: $('form#cashier'), autoSubmit: false, stopOnError: true, autoFocus: false, onFormValidated: function(err, results, form) { if(!err) { form[0].submit(); } else { Zepto.each(results, function(key, value){ if(value[1] != null) return errorMessages = value[1]; }) showMsg(errorMessages); } }, triggerType: 'submit', failSilently: true }); validator.addItem({ element: '#logon_id', required: true, errormessageRequired: '支付寶帳戶不能爲空', display: '支付寶帳戶', onItemValidated: function(error, message, elem) { if(error) window.Tracker&&Tracker.click('v5_need_login_new-' + elem.attr('name') + '-' + error); } }); var isInputEvent = "oninput" in document ? true : false; var inputEvent = isInputEvent ? "input" : 'keyup'; //RSA try { var dbits;var canary=0xdeadbeefcafe;var j_lm=((canary&0xffffff)==0xefcafe);function BigInteger(a,b,c){if(a!=null) if("number"==typeof a)this.fromNumber(a,b,c);else if(b==null&&"string"!=typeof a)this.fromString(a,256);else this.fromString(a,b);} function nbi(){return new BigInteger(null);} function am1(i,x,w,j,c,n){while(--n>=0){var v=x*this[i++]+w[j]+c;c=Math.floor(v/0x4000000);w[j++]=v&0x3ffffff;} return c;} function am2(i,x,w,j,c,n){var xl=x&0x7fff,xh=x>>15;while(--n>=0){var l=this[i]&0x7fff;var h=this[i++]>>15;var m=xh*l+h*xl;l=xl*l+((m&0x7fff)<<15)+w[j]+(c&0x3fffffff);c=(l>>>30)+(m>>>15)+xh*h+(c>>>30);w[j++]=l&0x3fffffff;} return c;} function am3(i,x,w,j,c,n){var xl=x&0x3fff,xh=x>>14;while(--n>=0){var l=this[i]&0x3fff;var h=this[i++]>>14;var m=xh*l+h*xl;l=xl*l+((m&0x3fff)<<14)+w[j]+c;c=(l>>28)+(m>>14)+xh*h;w[j++]=l&0xfffffff;} return c;} if(j_lm&&(navigator.appName=="Microsoft Internet Explorer")){BigInteger.prototype.am=am2;dbits=30;} else if(j_lm&&(navigator.appName!="Netscape")){BigInteger.prototype.am=am1;dbits=26;} else{BigInteger.prototype.am=am3;dbits=28;} BigInteger.prototype.DB=dbits;BigInteger.prototype.DM=((1<<dbits)-1);BigInteger.prototype.DV=(1<<dbits);var BI_FP=52;BigInteger.prototype.FV=Math.pow(2,BI_FP);BigInteger.prototype.F1=BI_FP-dbits;BigInteger.prototype.F2=2*dbits-BI_FP;var BI_RM="0123456789abcdefghijklmnopqrstuvwxyz";var BI_RC=new Array();var rr,vv;rr="0".charCodeAt(0);for(vv=0;vv<=9;++vv)BI_RC[rr++]=vv;rr="a".charCodeAt(0);for(vv=10;vv<36;++vv)BI_RC[rr++]=vv;rr="A".charCodeAt(0);for(vv=10;vv<36;++vv)BI_RC[rr++]=vv;function int2char(n){return BI_RM.charAt(n);} function intAt(s,i){var c=BI_RC[s.charCodeAt(i)];return(c==null)?-1:c;} function bnpCopyTo(r){for(var i=this.t-1;i>=0;--i)r[i]=this[i];r.t=this.t;r.s=this.s;} function bnpFromInt(x){this.t=1;this.s=(x<0)?-1:0;if(x>0)this[0]=x;else if(x<-1)this[0]=x+this.DV;else this.t=0;} function nbv(i){var r=nbi();r.fromInt(i);return r;} function bnpFromString(s,b){var k;if(b==16)k=4;else if(b==8)k=3;else if(b==256)k=8;else if(b==2)k=1;else if(b==32)k=5;else if(b==4)k=2;else{this.fromRadix(s,b);return;} this.t=0;this.s=0;var i=s.length,mi=false,sh=0;while(--i>=0){var x=(k==8)?s[i]&0xff:intAt(s,i);if(x<0){if(s.charAt(i)=="-")mi=true;continue;} mi=false;if(sh==0) this[this.t++]=x;else if(sh+k>this.DB){this[this.t-1]|=(x&((1<<(this.DB-sh))-1))<<sh;this[this.t++]=(x>>(this.DB-sh));} else this[this.t-1]|=x<<sh;sh+=k;if(sh>=this.DB)sh-=this.DB;} if(k==8&&(s[0]&0x80)!=0){this.s=-1;if(sh>0)this[this.t-1]|=((1<<(this.DB-sh))-1)<<sh;} this.clamp();if(mi)BigInteger.ZERO.subTo(this,this);} function bnpClamp(){var c=this.s&this.DM;while(this.t>0&&this[this.t-1]==c)--this.t;} function bnToString(b){if(this.s<0)return"-"+this.negate().toString(b);var k;if(b==16)k=4;else if(b==8)k=3;else if(b==2)k=1;else if(b==32)k=5;else if(b==4)k=2;else return this.toRadix(b);var km=(1<<k)-1,d,m=false,r="",i=this.t;var p=this.DB-(i*this.DB)%k;if(i-->0){if(p<this.DB&&(d=this[i]>>p)>0){m=true;r=int2char(d);} while(i>=0){if(p<k){d=(this[i]&((1<<p)-1))<<(k-p);d|=this[--i]>>(p+=this.DB-k);} else{d=(this[i]>>(p-=k))&km;if(p<=0){p+=this.DB;--i;}} if(d>0)m=true;if(m)r+=int2char(d);}} return m?r:"0";} function bnNegate(){var r=nbi();BigInteger.ZERO.subTo(this,r);return r;} function bnAbs(){return(this.s<0)?this.negate():this;} function bnCompareTo(a){var r=this.s-a.s;if(r!=0)return r;var i=this.t;r=i-a.t;if(r!=0)return(this.s<0)?-r:r;while(--i>=0)if((r=this[i]-a[i])!=0)return r;return 0;} function nbits(x){var r=1,t;if((t=x>>>16)!=0){x=t;r+=16;} if((t=x>>8)!=0){x=t;r+=8;} if((t=x>>4)!=0){x=t;r+=4;} if((t=x>>2)!=0){x=t;r+=2;} if((t=x>>1)!=0){x=t;r+=1;} return r;} function bnBitLength(){if(this.t<=0)return 0;return this.DB*(this.t-1)+nbits(this[this.t-1]^(this.s&this.DM));} function bnpDLShiftTo(n,r){var i;for(i=this.t-1;i>=0;--i)r[i+n]=this[i];for(i=n-1;i>=0;--i)r[i]=0;r.t=this.t+n;r.s=this.s;} function bnpDRShiftTo(n,r){for(var i=n;i<this.t;++i)r[i-n]=this[i];r.t=Math.max(this.t-n,0);r.s=this.s;} function bnpLShiftTo(n,r){var bs=n%this.DB;var cbs=this.DB-bs;var bm=(1<<cbs)-1;var ds=Math.floor(n/this.DB),c=(this.s<<bs)&this.DM,i;for(i=this.t-1;i>=0;--i){r[i+ds+1]=(this[i]>>cbs)|c;c=(this[i]&bm)<<bs;} for(i=ds-1;i>=0;--i)r[i]=0;r[ds]=c;r.t=this.t+ds+1;r.s=this.s;r.clamp();} function bnpRShiftTo(n,r){r.s=this.s;var ds=Math.floor(n/this.DB);if(ds>=this.t){r.t=0;return;} var bs=n%this.DB;var cbs=this.DB-bs;var bm=(1<<bs)-1;r[0]=this[ds]>>bs;for(var i=ds+1;i<this.t;++i){r[i-ds-1]|=(this[i]&bm)<<cbs;r[i-ds]=this[i]>>bs;} if(bs>0)r[this.t-ds-1]|=(this.s&bm)<<cbs;r.t=this.t-ds;r.clamp();} function bnpSubTo(a,r){var i=0,c=0,m=Math.min(a.t,this.t);while(i<m){c+=this[i]-a[i];r[i++]=c&this.DM;c>>=this.DB;} if(a.t<this.t){c-=a.s;while(i<this.t){c+=this[i];r[i++]=c&this.DM;c>>=this.DB;} c+=this.s;} else{c+=this.s;while(i<a.t){c-=a[i];r[i++]=c&this.DM;c>>=this.DB;} c-=a.s;} r.s=(c<0)?-1:0;if(c<-1)r[i++]=this.DV+c;else if(c>0)r[i++]=c;r.t=i;r.clamp();} function bnpMultiplyTo(a,r){var x=this.abs(),y=a.abs();var i=x.t;r.t=i+y.t;while(--i>=0)r[i]=0;for(i=0;i<y.t;++i)r[i+x.t]=x.am(0,y[i],r,i,0,x.t);r.s=0;r.clamp();if(this.s!=a.s)BigInteger.ZERO.subTo(r,r);} function bnpSquareTo(r){var x=this.abs();var i=r.t=2*x.t;while(--i>=0)r[i]=0;for(i=0;i<x.t-1;++i){var c=x.am(i,x[i],r,2*i,0,1);if((r[i+x.t]+=x.am(i+1,2*x[i],r,2*i+1,c,x.t-i-1))>=x.DV){r[i+x.t]-=x.DV;r[i+x.t+1]=1;}} if(r.t>0)r[r.t-1]+=x.am(i,x[i],r,2*i,0,1);r.s=0;r.clamp();} function bnpDivRemTo(m,q,r){var pm=m.abs();if(pm.t<=0)return;var pt=this.abs();if(pt.t<pm.t){if(q!=null)q.fromInt(0);if(r!=null)this.copyTo(r);return;} if(r==null)r=nbi();var y=nbi(),ts=this.s,ms=m.s;var nsh=this.DB-nbits(pm[pm.t-1]);if(nsh>0){pm.lShiftTo(nsh,y);pt.lShiftTo(nsh,r);} else{pm.copyTo(y);pt.copyTo(r);} var ys=y.t;var y0=y[ys-1];if(y0==0)return;var yt=y0*(1<<this.F1)+((ys>1)?y[ys-2]>>this.F2:0);var d1=this.FV/yt,d2=(1<<this.F1)/yt,e=1<<this.F2;var i=r.t,j=i-ys,t=(q==null)?nbi():q;y.dlShiftTo(j,t);if(r.compareTo(t)>=0){r[r.t++]=1;r.subTo(t,r);} BigInteger.ONE.dlShiftTo(ys,t);t.subTo(y,y);while(y.t<ys)y[y.t++]=0;while(--j>=0){var qd=(r[--i]==y0)?this.DM:Math.floor(r[i]*d1+(r[i-1]+e)*d2);if((r[i]+=y.am(0,qd,r,j,0,ys))<qd){y.dlShiftTo(j,t);r.subTo(t,r);while(r[i]<--qd)r.subTo(t,r);}} if(q!=null){r.drShiftTo(ys,q);if(ts!=ms)BigInteger.ZERO.subTo(q,q);} r.t=ys;r.clamp();if(nsh>0)r.rShiftTo(nsh,r);if(ts<0)BigInteger.ZERO.subTo(r,r);} function bnMod(a){var r=nbi();this.abs().divRemTo(a,null,r);if(this.s<0&&r.compareTo(BigInteger.ZERO)>0)a.subTo(r,r);return r;} function Classic(m){this.m=m;} function cConvert(x){if(x.s<0||x.compareTo(this.m)>=0)return x.mod(this.m);else return x;} function cRevert(x){return x;} function cReduce(x){x.divRemTo(this.m,null,x);} function cMulTo(x,y,r){x.multiplyTo(y,r);this.reduce(r);} function cSqrTo(x,r){x.squareTo(r);this.reduce(r);} Classic.prototype.convert=cConvert;Classic.prototype.revert=cRevert;Classic.prototype.reduce=cReduce;Classic.prototype.mulTo=cMulTo;Classic.prototype.sqrTo=cSqrTo;function bnpInvDigit(){if(this.t<1)return 0;var x=this[0];if((x&1)==0)return 0;var y=x&3;y=(y*(2-(x&0xf)*y))&0xf;y=(y*(2-(x&0xff)*y))&0xff;y=(y*(2-(((x&0xffff)*y)&0xffff)))&0xffff;y=(y*(2-x*y%this.DV))%this.DV;return(y>0)?this.DV-y:-y;} function Montgomery(m){this.m=m;this.mp=m.invDigit();this.mpl=this.mp&0x7fff;this.mph=this.mp>>15;this.um=(1<<(m.DB-15))-1;this.mt2=2*m.t;} function montConvert(x){var r=nbi();x.abs().dlShiftTo(this.m.t,r);r.divRemTo(this.m,null,r);if(x.s<0&&r.compareTo(BigInteger.ZERO)>0)this.m.subTo(r,r);return r;} function montRevert(x){var r=nbi();x.copyTo(r);this.reduce(r);return r;} function montReduce(x){while(x.t<=this.mt2) x[x.t++]=0;for(var i=0;i<this.m.t;++i){var j=x[i]&0x7fff;var u0=(j*this.mpl+(((j*this.mph+(x[i]>>15)*this.mpl)&this.um)<<15))&x.DM;j=i+this.m.t;x[j]+=this.m.am(0,u0,x,i,0,this.m.t);while(x[j]>=x.DV){x[j]-=x.DV;x[++j]++;}} x.clamp();x.drShiftTo(this.m.t,x);if(x.compareTo(this.m)>=0)x.subTo(this.m,x);} function montSqrTo(x,r){x.squareTo(r);this.reduce(r);} function montMulTo(x,y,r){x.multiplyTo(y,r);this.reduce(r);} Montgomery.prototype.convert=montConvert;Montgomery.prototype.revert=montRevert;Montgomery.prototype.reduce=montReduce;Montgomery.prototype.mulTo=montMulTo;Montgomery.prototype.sqrTo=montSqrTo;function bnpIsEven(){return((this.t>0)?(this[0]&1):this.s)==0;} function bnpExp(e,z){if(e>0xffffffff||e<1)return BigInteger.ONE;var r=nbi(),r2=nbi(),g=z.convert(this),i=nbits(e)-1;g.copyTo(r);while(--i>=0){z.sqrTo(r,r2);if((e&(1<<i))>0)z.mulTo(r2,g,r);else{var t=r;r=r2;r2=t;}} return z.revert(r);} function bnModPowInt(e,m){var z;if(e<256||m.isEven())z=new Classic(m);else z=new Montgomery(m);return this.exp(e,z);} BigInteger.prototype.copyTo=bnpCopyTo;BigInteger.prototype.fromInt=bnpFromInt;BigInteger.prototype.fromString=bnpFromString;BigInteger.prototype.clamp=bnpClamp;BigInteger.prototype.dlShiftTo=bnpDLShiftTo;BigInteger.prototype.drShiftTo=bnpDRShiftTo;BigInteger.prototype.lShiftTo=bnpLShiftTo;BigInteger.prototype.rShiftTo=bnpRShiftTo;BigInteger.prototype.subTo=bnpSubTo;BigInteger.prototype.multiplyTo=bnpMultiplyTo;BigInteger.prototype.squareTo=bnpSquareTo;BigInteger.prototype.divRemTo=bnpDivRemTo;BigInteger.prototype.invDigit=bnpInvDigit;BigInteger.prototype.isEven=bnpIsEven;BigInteger.prototype.exp=bnpExp;BigInteger.prototype.toString=bnToString;BigInteger.prototype.negate=bnNegate;BigInteger.prototype.abs=bnAbs;BigInteger.prototype.compareTo=bnCompareTo;BigInteger.prototype.bitLength=bnBitLength;BigInteger.prototype.mod=bnMod;BigInteger.prototype.modPowInt=bnModPowInt;BigInteger.ZERO=nbv(0);BigInteger.ONE=nbv(1);function Arcfour(){this.i=0;this.j=0;this.S=new Array();} function ARC4init(key){var i,j,t;for(i=0;i<256;++i) this.S[i]=i;j=0;for(i=0;i<256;++i){j=(j+this.S[i]+key[i%key.length])&255;t=this.S[i];this.S[i]=this.S[j];this.S[j]=t;} this.i=0;this.j=0;} function ARC4next(){var t;this.i=(this.i+1)&255;this.j=(this.j+this.S[this.i])&255;t=this.S[this.i];this.S[this.i]=this.S[this.j];this.S[this.j]=t;return this.S[(t+this.S[this.i])&255];} Arcfour.prototype.init=ARC4init;Arcfour.prototype.next=ARC4next;function prng_newstate(){return new Arcfour();} var rng_psize=256;var rng_state;var rng_pool;var rng_pptr;function rng_seed_int(x){rng_pool[rng_pptr++]^=x&255;rng_pool[rng_pptr++]^=(x>>8)&255;rng_pool[rng_pptr++]^=(x>>16)&255;rng_pool[rng_pptr++]^=(x>>24)&255;if(rng_pptr>=rng_psize)rng_pptr-=rng_psize;} function rng_seed_time(){rng_seed_int(new Date().getTime());} if(rng_pool==null){rng_pool=new Array();rng_pptr=0;var t;if(window.crypto&&window.crypto.getRandomValues){var ua=new Uint8Array(32);window.crypto.getRandomValues(ua);for(t=0;t<32;++t) rng_pool[rng_pptr++]=ua[t];} if(navigator.appName=="Netscape"&&navigator.appVersion<"5"&&window.crypto){var z=window.crypto.random(32);for(t=0;t<z.length;++t) rng_pool[rng_pptr++]=z.charCodeAt(t)&255;} while(rng_pptr<rng_psize){t=Math.floor(65536*Math.random());rng_pool[rng_pptr++]=t>>>8;rng_pool[rng_pptr++]=t&255;} rng_pptr=0;rng_seed_time();} function rng_get_byte(){if(rng_state==null){rng_seed_time();rng_state=prng_newstate();rng_state.init(rng_pool);for(rng_pptr=0;rng_pptr<rng_pool.length;++rng_pptr) rng_pool[rng_pptr]=0;rng_pptr=0;} return rng_state.next();} function rng_get_bytes(ba){var i;for(i=0;i<ba.length;++i)ba[i]=rng_get_byte();} function SecureRandom(){} SecureRandom.prototype.nextBytes=rng_get_bytes;function parseBigInt(str,r){return new BigInteger(str,r);} function linebrk(s,n){var ret="";var i=0;while(i+n<s.length){ret+=s.substring(i,i+n)+"\n";i+=n;} return ret+s.substring(i,s.length);} function byte2Hex(b){if(b<0x10) return"0"+b.toString(16);else return b.toString(16);} function pkcs1pad2(s,n){if(n<s.length+11){alert("Message too long for RSA");return null;} var ba=new Array();var i=s.length-1;while(i>=0&&n>0){var c=s.charCodeAt(i--);if(c<128){ba[--n]=c;} else if((c>127)&&(c<2048)){ba[--n]=(c&63)|128;ba[--n]=(c>>6)|192;} else{ba[--n]=(c&63)|128;ba[--n]=((c>>6)&63)|128;ba[--n]=(c>>12)|224;}} ba[--n]=0;var rng=new SecureRandom();var x=new Array();while(n>2){x[0]=0;while(x[0]==0)rng.nextBytes(x);ba[--n]=x[0];} ba[--n]=2;ba[--n]=0;return new BigInteger(ba);} function RSAKey(){this.n=null;this.e=0;this.d=null;this.p=null;this.q=null;this.dmp1=null;this.dmq1=null;this.coeff=null;} function RSASetPublic(N,E){if(N!=null&&E!=null&&N.length>0&&E.length>0){this.n=parseBigInt(N,16);this.e=parseInt(E,16);} else alert("Invalid RSA public key");} function RSADoPublic(x){return x.modPowInt(this.e,this.n);} function RSAEncrypt(text){var m=pkcs1pad2(text,(this.n.bitLength()+7)>>3);if(m==null)return null;var c=this.doPublic(m);if(c==null)return null;var h=c.toString(16);if((h.length&1)==0)return h;else return"0"+h;} RSAKey.prototype.doPublic=RSADoPublic;RSAKey.prototype.setPublic=RSASetPublic;RSAKey.prototype.encrypt=RSAEncrypt;var b64map="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";var b64padchar="=";function hex2b64(h){var i;var c;var ret="";for(i=0;i+3<=h.length;i+=3){c=parseInt(h.substring(i,i+3),16);ret+=b64map.charAt(c>>6)+b64map.charAt(c&63);} if(i+1==h.length){c=parseInt(h.substring(i,i+1),16);ret+=b64map.charAt(c<<2);} else if(i+2==h.length){c=parseInt(h.substring(i,i+2),16);ret+=b64map.charAt(c>>2)+b64map.charAt((c&3)<<4);} while((ret.length&3)>0)ret+=b64padchar;return ret;} var rsa_n = 'B98DC71833036E62C92BF6ABA5DFDDABBD44E52932CAE2026ED2A71C22E7681644A3233276F2EB7B29EC56CB720A3B8A8BFAEEA3E5E00D03E4E82203F676EBF5'; var rsa_e = '10001'; var encrypt = function(data) { var setRSA = new RSAKey(); setRSA.setPublic(rsa_n, rsa_e); var res = setRSA.encrypt(data); if(res) { return linebrk(hex2b64(res), 64); } else { return '*'; } } var pwd = $('.J-pwd'); var encryptpwd = $('.J-encryptpwd'); var isPaste = false; var clean = function () { pwd.val(''); encryptpwd.val(''); } clean(); var setRange = function (el) { el.setSelectionRange(parseInt(el.value.length + 1), parseInt(el.value.length + 1)) } pwd.on('focus',function(e){ var el = e.target; setRange(el); }); pwd.on('keydown',function(e){ var el = e.target; if (e.which === 8 || e.which === 46) clean(); setRange(el); }); pwd.on('keyup',function(e){ var el = e.target; setRange(el); }); pwd.on('paste',function(e){ isPaste = true; }); //默認清空加密(瀏覽器點返回會保留以前的值) encryptpwd.val(''); pwd.on(inputEvent,function(e){ var el = e.target; if (isPaste) clean(); isPaste = false; setRange(el); var currentPW = el.value.split('*').slice(-1).toString(); var encryptPW = encryptpwd[0].value; //刪除(觸發input事件,未獲取刪除keycode) if(currentPW.length === 0) { encryptpwd[0].value = encryptpwd[0].value.split(',').slice(0, el.value.length).toString(); } else { //新增 for (var i=0;i < currentPW.length;i++) { var outkey = encrypt(currentPW[i]); if(encryptpwd.val() === ''){ encryptpwd.val(outkey); } else { encryptpwd[0].value += ',' + outkey; } } el.value = el.value.replace(/\S/g,"*") } }); }catch(e){} validator.addItem({ element: '#pwd', required: true, errormessageRequired: '請填寫支付密碼', display: '支付密碼', onItemValidate: function(error, message, elem) { if($('.J-encryptpwd').val() === '') { $('.J-encryptpwd').val($('.J-pwd').val()); } }, onItemValidated: function(error, message, elem) { if($('.J-encryptpwd').val() === '') { $('.J-encryptpwd').val($('.J-pwd').val()); } if(error) { $('.J-pwd').val(''); $('.J-encryptpwd').val(''); } if(error) window.Tracker&&Tracker.click('v5_need_login_new-' + elem.attr('name') + '-' + error); } }); }); $(function(){ $('.J-back').on('click',function(e){ window.history.back(); e.preventDefault(); }); $('.J-loading').addClass('fn-hide'); $('.J-open-protocol').on('click',function(e){ var el = $(this); Zepto.dialog.show({ message: '<div style="height: 280px;-webkit-overflow-scrolling:touch;overflow:auto;"><iframe style="height: 280px;width: 100%;overflow: auto;" src="' + el.attr('href') + '" frameborder="0" scrolling="auto" allowTransparency="true"></iframe></div>', buttons: '肯定', complete: function () { Zepto.dialog.hide(); } }); e.preventDefault(); }); // fix dialog連續閃動的問題 Zepto.dialog.hide = function() { $('body').find('.am-dialog-mask').remove(); $('body').find('.am-dialog-box').remove(); } }); </script> <script type="text/javascript"> var form_tk = "b63232f9568b71d0ad1425ca684e67f9b546a51c877e484f987868163c47e6f2RZ11"; var json_ua; </script> <script src="https://rds.alipay.com/ua_mobilecashier_login.js?t=2017081515"></script> <script> (function (w, d, t) { var s = d.createElement(t), m = d.getElementsByTagName(t)[0]; s.async = 1; s.src = "https://g.alicdn.com/sd/pointman/js/pt2.js?f=m&_=" + Math.floor((new Date()).getTime() / 36e5); m.parentNode.insertBefore(s, m); w._pointman_q = w._pointman_q || []; _pointman_q.push(["um", function (um) { um.init({ timeout: 3000, token:'P14c3df62cee8d4bb94634ae243d1ad82', userid: '', serviceLocation: "cn", appName: 'mobileclientgw' }); }]); })(window, document, "script"); </script> <footer> <div class="alipay-logo"></div> <div id="ServerNum">mobileclientgw-30-5</div> </footer> <!-- CMS:安全支付客戶端網關/common/footer.vm開始:mobileclientgw/common/footer.vm --> <script type="text/javascript"> if(navigator.userAgent.indexOf('sdk') > 0) {$('input[data-format]').attr('data-format', '100')} //12.03下線 if(window.Zepto && Zepto.dialog && $('.J-header-return') != -1){ Zepto.dialog.hide = function() { $('body').find('.am-dialog-mask').animate({ opacity: 0 }, 400, 'ease-out', function(){ $(this).css('display', 'none'); }); $('body').find('.am-dialog-box').animate({ opacity: 0 }, 400, 'ease-out', function(){ $(this).css('display', 'none'); }); window.setTimeout(function(){ $('body').find('.am-dialog-mask').remove(); $('body').find('.am-dialog-box').remove(); },1000); } } </script><!-- CMS:安全支付客戶端網關/common/footer.vm結束:mobileclientgw/common/footer.vm --></body> </html>
改造到最後呢,頁面邏輯清爽多了,再有新的模塊,寫好以後別人直接調用就能夠了,write once, run everywhere .
define(function(require) { var $ = require("jquery"), $body = $(document.body), setDate = require("components/setDate"), selectCity = require("components/selectCity"), commonTools = require("tools/commonTools"), FastClick = require("fastClick"), myLayer = require("myLayer"); //內部統計 var webTrends = require("webTrends"); webTrends.init(); // 百度統計 var baiduTrends = require("baiduTrends"); baiduTrends.init(); // 初始化時間選擇 setDate.dateTime.init(); // 選擇目的地 selectCity.init(); var actionList = { 'applyInsurance' :function(){ //xxx } });
完整的代碼就不展現了,都是一些邏輯,沒什麼好看的。
花了大概一個周的時間初步重構了一下項目代碼,改得很粗糙,只是作了一些大概的拆分,畢竟遺留的代碼太多,須要和小夥伴一塊兒作這個事。
因爲公司標裝的電腦用不了npm那些,最後的一步是我在mac上弄好,而後拷貝到公司電腦上,中間還出了不少問題,不過好在能跑了,至於最後能不能用起來..只能說,努力吧。
seajs 能夠說是上個年代的產物了,不過在一些老舊項目中,依然能夠發揮光和熱。
寫到這裏差很少也要結束了,我呢,也算完成了給本身定的一個小目標,不算多大的貢獻,只當給本身一個交代。
以上大概就是所有內容,但願給你們帶來一些啓發和幫助,謝謝。