【PC网站前端架构探讨系列】关于中小型PC网站前端架构方案的讨论与实践
目 录
1.遇到的问题
2.目标
3.探讨
4.架构设想
5.流程
6.初步实现
7.存在问题
8.最后
遇到的问题
我在这个系列上篇文章 已经讲解并开始逐步应用模块化思想,不知大家还记不记得,题目:【PC网站前端架构探讨系列】结合公司网站首页,谈前端模块化开发与网站性能优化实践 。但是,仍然会存在下列问题:
问题1----模块内部脚本和页面联系密切
问题2----所有脚本文件集中放于一个目录,脚本目录不清晰,没有层次
当然还有其他很多问题,但就以上两大问题来说,会对后期代码维护带来不便!
目 标
尽量将页面和脚本进行分离,以及方便开发人员维护管理,形成一个固定的代码规范;其二,项目的结构清晰,层次明确,功能突出。所以,需要设计一个合理的前端架构来解决当前以及后期会遇到的问题
探 讨
思想方面:
针对耦合性问题,业界流行的新一种架构思想——“MVC””MVVC”,但大多这种思想用于WAP开发中,国内很少的PC网站有用过,比如,有道好像用的是Backbone框架…
技术角度:
在seajs模块划分的基础上
1. backbone+underscore(MVC)
2. knockout(MVVM)
目前这两种用的较多,而且社区文档比较多,但是都比较适合单页面的应用,最主要就是开发方式会有很大转变….很难上手…感觉不太适合普通中小型的PC网站开发以及后期维护
下面列出相关示例代码:(Backbone)
1 define('module/home/index', ['backbone'], function(reuqire) { 2 var Backbone = reuqire('backbone'); 3 App.Models.Home = Backbone.Model.extend({}); 4 5 App.Collections.Home = Backbone.Collection.extend({ 6 model: App.Models.Home 7 }); 8 9 App.Views.Home = Backbone.View.extend({ 10 el: '#container', 11 initialize: function(c) { 12 this.Collections = c; 13 this.render(); 14 }, 15 render: function() { 16 var html = ''; 17 this.Collections.each(function(m) { 18 html += '<div><a href="' + m.get('link') + '">' + m.get('name') + '</a></div>'; 19 }); 20 this.$el.html(html); 21 } 22 }) 23 24 return function() { 25 //模拟数据 26 var hc = new App.Collections.Home(); 27 hc.add([ 28 {'name': '加载模块A', 'link': '#at/m/a/name:moduleA/other:nothing'}, 29 {'name': '加载模块B', 'link': '#at/m/b'} 30 ]); 31 new App.Views.Home(hc); 32 } 33 });
紧接着:(knockout)
1 <html xmlns="http://www.w3.org/1999/xhtml" > 2 <head> 3 <title>Knockout学习一</title> 4 <script src="Scripts/knockout-3.0.0.js" type="text/javascript"></script> 5 <script src="Scripts/jquery-1.10.2.min.js" type="text/javascript"></script> 6 </head> 7 <body> 8 9 <div> 10 <span data-bind="text: personName"></span> 11 </div> 12 13 </body> 14 <script type="text/javascript"> 15 var myViewModel = { 16 personName: ko.observable('张三'), 17 personAge: ko.observable(12) 18 }; 19 20 $(function() { 21 ko.applyBindings(myViewModel); 22 }); 23 24 </script> 25 </html>
另外,一个完整的前端框架要包括以下方面:
1. 解耦
2. 模块化
3. 统一的代码书写结构
4. 组件库
5. 事件处理机制 ……
目前互联网发展迅速,技术更新太快,所以,针对以上方面使用目前的技术手段,完全可以实现,就是好多文档不全,教程不清晰,关键比较零散,不同技术组合起来会遇到很多问题,问题再多,时间充足的话,也会找到解决的办法。我这里简单说下解决的思路:
1. 解耦问题--可以使用模板来达到业务和页面分离
2. 模块化问题--模块化技术好多,requireJS、seajs等,我这里用的是seajs
3. 代码结构—json格式
4. 组件库—define封装,定义成seajs模块,定义属性、选择器、方法、事件等
5. 事件处理机制 —事件的单独封装,统一的注册机制,调用机制(kissy 做的很好,个人还没研究透)
下面先做个简单的架构设想 吧!
架构设想
这里看图就不多讲了,直接看下面的关系吧!
流 程
模块之间的关系以及调用流程如下:
初步实现
说到技术,推荐多去学习下百度阿里腾讯等的前端技术,相对比较贴地气,比较赶潮流. .比如,之前在学习seajs 的时候,无意中发现一些网站的脚本从风格、写法、思想上,都值得我学习一下。所以,我经常特意把上面的代码扒下来,研究一番…..
废话不多说,这里把我部分代码分享出来:
1.package/main.js (核心工具类库)
1 /** 2 * 核心工具类 文件 v20151023 3 */ 4 (function() { 5 var mods = [], 6 version = parseFloat(seajs.version); 7 define(["lib/jquery"],function(require, exports, module) { 8 var uri = module.uri || module.id, 9 m = uri.split("?")[0].match(/^(.+\/)([^\/]*?)(?:\.js)?.J/i), 10 root = m && m[1], 11 name = m && "./" + m[2].substring(0,m[2].length), 12 i = 0, 13 len = mods.length, 14 curr, args, undefined; 15 name = name.replace(/\.r[0-9]{15}/, ""); 16 for (; i < len; i++) { 17 args = mods[i]; 18 if (typeof args[0] === "string") { 19 name === args[0] && (curr = args[2]); 20 args[0] = root + args[0].replace("./", ""); 21 version > 1 && define.apply(this, args); 22 } 23 } 24 mods = []; 25 require.get = require; 26 return typeof curr === "function" ? curr.apply(this, arguments) : require; 27 }); 28 define.pack = function() { 29 mods.push(arguments); 30 version > 1 || define.apply(null, arguments) 31 } 32 })(); 33 define.pack("./request", ["lib/jquery","./random","./domains"], function(require, exports, module) { 34 var Random = require("./random"); 35 var J = require("lib/jquery"); 36 var Domains=require("./domains"); 37 var MOD = { 38 _Config: { 39 domain: Domains.base 40 }, 41 request:function(conf){ 42 var conf = { 43 type: conf.type, 44 async: conf.async || false, 45 url: this._Config.domain+conf.url, 46 dataType: conf.dataType || 'json', 47 data: conf.data || {}, 48 beforeSend: conf.before, 49 success: conf.success, 50 complete: conf.complete, 51 error: conf.error 52 }; 53 J.ajax(conf); 54 }, 55 get: function(conf) { 56 return MOD.request({ 57 type: 'get', 58 async: conf.async, 59 url: conf.url, 60 dataType: conf.dataType, 61 data: conf.data, 62 beforeSend: conf.callback.beforeSend, 63 success: conf.callback.success, 64 complete: conf.callback.complete, 65 error: conf.callback.error 66 }) 67 }, 68 post: function(conf) { 69 return MOD.request({ 70 type: 'post', 71 async: conf.async, 72 url: conf.url, 73 dataType: conf.dataType, 74 data: conf.data, 75 beforeSend: conf.callback.beforeSend, 76 success: conf.callback.success, 77 complete: conf.callback.complete, 78 error: conf.callback.error 79 }) 80 }, 81 jsonp: function(conf) { 82 conf.dataType = "jsonp"; 83 return MOD.request(conf) 84 }, 85 src: function(conf) { 86 conf = conf || {}; 87 var defConfig = this._Config; 88 var url, data = { 89 domain: conf.url || defConfig.domain, 90 _: Random() 91 }; 92 if (data.domain) { 93 url = data.domain+"?_=" + data._; 94 (new Image).src = url 95 } 96 } 97 }; 98 return MOD; 99 }); 100 define.pack("./random", [], function(require, exports, module) { 101 var MOD = function() { 102 var rs = (new Date).getTime() + Math.ceil(Math.random() * 1E4); 103 return rs; 104 }; 105 return MOD; 106 }); 107 define.pack("./template", ['lib/jquery'], function(require, exports, module) { 108 var J = require("lib/jquery"); 109 var MOD = { 110 parse: function() { 111 var cache = {}; 112 return function(str, data) { 113 if (typeof str === "function") return data ? str(data) : str; 114 var fn = !/\W/.test(str) ? cache[str] = cache[str] || arguments.callee.call(this, document.getElementById(str).innerHTML) : new Function("obj", "var p=[],print=function(){p.push.apply(p,arguments);};" + "with(obj){p.push('" + str.replace(/[\r\t\n]/g, 115 " ").split("<%").join("\t").replace(/((^|%>)[^\t]*)'/g, "J1\r").replace(/\t=(.*?)%>/g, "',J1,'").split("\t").join("');").split("%>").join("p.push('").split("\r").join("\\'") + "');}return p.join('');"); 116 if (data){ 117 return fn(data); 118 } else { 119 return fn; 120 } 121 } 122 }(), 123 render:function(opts){ 124 var html = ''; 125 var conf = J.extend({ 126 container: opts.container instanceof jQuery ? opts.container : J(opts.container), 127 tmpl: typeof(opts.tmpl) =='string' ? opts.tmpl 128 : opts.tmpl.join(''), 129 options: opts.options || {} 130 }, {}); 131 html += MOD.parse(conf.tmpl,conf.options); 132 conf.container.html(html); 133 } 134 }; 135 return MOD; 136 }); 137 define.pack("./browser",["lib/jquery"],function(require,exports,module){ 138 var J = require("lib/jquery"); 139 var MOD={ 140 _getBrower:function(){ 141 var ua = navigator.userAgent, 142 jqBrowser = J.browser, 143 jqVersion = jqBrowser.version, 144 browser = '', 145 ver = ''; 146 if (jqBrowser.msie) { 147 browser = 'ie'; 148 ver = Math.floor(jqVersion); 149 if (ver < 6) { 150 ver = 6; 151 } 152 if (ver > 10) { 153 ver = 10; 154 } 155 } else if (jqBrowser.webkit) { 156 browser = 'safari'; 157 if (ua.indexOf('Chrome') !== -1) { 158 browser = 'chrome'; 159 } 160 } else if (jqBrowser.mozilla) { 161 browser = 'firefox'; 162 } else if (jqBrowser.opera) { 163 browser = 'opera'; 164 } 165 if (!browser) { 166 browser = 'other'; 167 ver = ''; 168 } 169 return '' + browser + ver; 170 }, 171 isIE:function(v){ 172 v = v || J.browser.version; 173 return this._getBrowser=='ie'+v.toString(); 174 } 175 }; 176 return MOD; 177 }); 178 define.pack('./domains',[],function(require,exports,module){ 179 var MOD={ 180 base: basePath || "https://www.ddshenbian.com" 181 }; 182 return MOD; 183 }); 184 define.pack("./cookie", ["lib/jquery", "./domains"], function(require, exports, module) { 185 var J = require("lib/jquery"); 186 var Domains = require("./domains"); 187 188 function MOD(name, value, options) { 189 if (typeof value != "undefined") { 190 options = options || { 191 "domain": Domains.base 192 }; 193 if (value === null) { 194 value = ""; 195 } 196 var expires = ""; 197 if (options.expires && (typeof options.expires == "number" || options.expires.toUTCString)) { 198 var date; 199 if (typeof options.expires == "number") { 200 date = new Date; 201 date.setTime(date.getTime() + options.expires * 202 1E3) 203 } else date = options.expires; 204 expires = "; expires=" + date.toUTCString() 205 } 206 var path = options.path ? "; path=" + options.path : ""; 207 var domain = options.domain ? "; domain=" + options.domain : ""; 208 var secure = options.secure ? "; secure" : ""; 209 document.cookie = [encodeURIComponent(name), "=", encodeURIComponent(value), expires, path, domain, secure].join("") 210 } else { 211 var cookieValue = null, 212 name = encodeURIComponent(name); 213 if (document.cookie && document.cookie != "") { 214 var cookies = document.cookie.split(";"); 215 for (var i = 0; i < cookies.length; i++) { 216 var cookie = J.trim(cookies[i]); 217 if (cookie.substring(0, name.length + 218 1) == name + "=") { 219 cookieValue = decodeURIComponent(cookie.substring(name.length + 1)); 220 break 221 } 222 } 223 } 224 return cookieValue 225 } 226 } 227 return MOD; 228 }); 229 define.pack("./html", [], function(require, exports, module) { 230 var MOD = function() { 231 var encodeMap = { 232 reg: /([&"'<>])/gmi, 233 "&": "&", 234 '"': """, 235 "'": "'", 236 "<": "<", 237 ">": ">" 238 }, 239 decodeMap = { 240 reg: /(<)|(")|(')|(')|(')|(&)|(>)/gim, 241 "<": "<", 242 ">": ">", 243 """: '"', 244 "'": "'", 245 "'": "'", 246 "'": "'", 247 "&": "&" 248 }, 249 encode = function(J0, c) { 250 return encodeMap[c] 251 }, 252 decode = function(c) { 253 return decodeMap[c] 254 }; 255 return { 256 htmlEncode: function(str) { 257 if (typeof str != "string") str = str + ""; 258 return str.replace(encodeMap.reg, 259 encode) 260 }, 261 htmlDecode: function(str) { 262 if (typeof str != "string") str = str + ""; 263 return str.replace(decodeMap.reg, decode) 264 } 265 } 266 }(); 267 return MOD; 268 }); 269 define.pack("./error", [], function(require, exports, module) { 270 function MOD(mname,msg) { 271 throw "DD.error[" + mname + "]\u8f93\u51fa\u9519\u8bef\uff1a" + msg; 272 } 273 return MOD; 274 }); 275 define.pack("./log", ["lib/jquery"], function(require, exports, module) { 276 var J = require("lib/jquery"); 277 var MOD = function() { 278 var logPanel, logPanelBd; 279 return function() { 280 try { 281 if (J.browser.msie) console.log([].slice.call(arguments).join("")); 282 else console.log.apply(console, [].slice.call(arguments)) 283 } catch (e) {} 284 } 285 }(); 286 return MOD; 287 }); 288 define.pack("./helper", ["lib/jquery", "./cookie"], function(require, exports, module) { 289 var J = require("lib/jquery"); 290 var Cookie = require("./cookie"); 291 var MOD = { 292 getURLArgs: function(str, k) { 293 str = str ? str : location.href; 294 var s = str.indexOf("?"); 295 var e = str.indexOf("#") == -1 ? str.length : str.indexOf("#"); 296 var r = {}; 297 if (s != -1) { 298 var ts = str.substring(s + 1, e); 299 ts = ts.split("&"); 300 var t; 301 for (var i = 0; i < ts.length; i++) { 302 t = ts[i].split("="); 303 if (t.length == 2) r[t[0]] = t[1] 304 } 305 } 306 if (k) return r[k] ? r[k] : false; 307 return r 308 }, 309 isEmpty: function(v) { 310 if (v != null && (typeof v == 311 "object" || typeof v == "function")) { 312 if (J.isArray(v) && v.length == 0) return true; 313 return false 314 } 315 return "" == v || undefined == v || null == v ? true : false 316 }, 317 filterXSS: function(cont) { 318 cont = cont.replace(/&/g, "&"); 319 cont = cont.replace(/</g, "<").replace(/>/g, ">"); 320 cont = cont.replace(/\'/g, "'").replace(/\"/g, """); 321 return cont 322 }, 323 str2Args: function(query, split) { 324 var args = {}; 325 query = query || ""; 326 split = split || "&"; 327 var pairs = query.split(split); 328 for (var i = 0; i < pairs.length; i++) { 329 var pos = pairs[i].indexOf("="); 330 if (pos == -1) continue; 331 var argname = pairs[i].substring(0, pos); 332 var value = pairs[i].substring(pos + 1); 333 args[argname] = this.filterXSS(decodeURIComponent(value)) 334 } 335 return args 336 }, 337 args2Str: function(args, split) { 338 split = split || "&"; 339 var key, rtn = "", 340 sp = ""; 341 for (key in args) { 342 rtn += sp + key + "=" + 343 encodeURIComponent(args[key]); 344 sp = split 345 } 346 return rtn 347 }, 348 formatDate: function(mDate, fmt) { 349 var o = { 350 "M+": mDate.getMonth() + 1, 351 "d+": mDate.getDate(), 352 "h+": mDate.getHours() % 12 == 0 ? 12 : mDate.getHours() % 12, 353 "H+": mDate.getHours(), 354 "m+": mDate.getMinutes(), 355 "s+": mDate.getSeconds(), 356 "q+": Math.floor((mDate.getMonth() + 3) / 3), 357 "S": mDate.getMilliseconds() 358 }, 359 week = { 360 "0": "\u65e5", 361 1: "\u4e00", 362 2: "\u4e8c", 363 3: "\u4e09", 364 4: "\u56db", 365 5: "\u4e94", 366 6: "\u516d" 367 }; 368 if (/(y+)/.test(fmt)) fmt = fmt.replace(RegExp.J1, (mDate.getFullYear() + "").substr(4 - RegExp.J1.length)); 369 if (/(E+)/.test(fmt)) fmt = fmt.replace(RegExp.J1, (RegExp.J1.length > 1 ? RegExp.J1.length > 2 ? "\u661f\u671f" : "\u5468" : "") + week[mDate.getDay() + ""]); 370 for (var k in o) 371 if ((new RegExp("(" + k + ")")).test(fmt)) fmt = fmt.replace(RegExp.J1, RegExp.J1.length == 1 ? o[k] : ("00" + o[k]).substr(("" + o[k]).length)); 372 return fmt; 373 }, 374 toThousands:function(num) { 375 var num = (num || 0).toString(), re = /\d{3}J/, result = ''; 376 while ( re.test(num) ) { 377 result = RegExp.lastMatch + result; 378 if (num !== RegExp.lastMatch) { 379 result = ',' + result; 380 num = RegExp.leftContext; 381 } else { 382 num = ''; 383 break; 384 } 385 } 386 if (num) { result = num + result; } 387 return result; 388 } 389 }; 390 return MOD; 391 }); 392 define.pack("./response",["./error"],function(require, exports, module){ 393 var error = require("./error"); 394 var MOD=function(res,autoCode){ 395 var code = res.code; 396 if(code){ 397 return code == (autoCode || 1)?(res.obj || res.msg):res.msg; 398 } 399 error(); 400 }; 401 return MOD; 402 }); 403 define.pack("./json",[],function(require, exports, module){ 404 return { 405 isJSON : function(obj){ 406 var isjson = typeof(obj) == "object" && Object.prototype.toString.call(obj).toLowerCase() == "[object object]" && !obj.length; 407 return isjson; 408 } 409 }; 410 }); 411 define.pack("./user",['jquery','./cookie','./json','./domains','./template'],function(require, exports, module){ 412 var Domains = require("./domains"), 413 json = require("./json"), 414 template = require("./template"), 415 cookie = require("./cookie"), 416 J = require("jquery"); 417 var MOD = { 418 logout: function() { 419 J('#header').delegate('a#quit', 'click', function() { 420 seajs.use("package/data", function(d) { 421 if(d.logout == 0){ 422 window.location.reload(); 423 } 424 }) 425 }) 426 }, 427 login: function(){ 428 var that = this; 429 var loginTmpl = ['<a class="uname fr" id="_userName" href="<%=domain%>/auth/account/myaccount_index">','<%=_userName%>','<a class="msg-link" id="msgbox" style="<%=_isShow%>">','<em>','<%=_msgNum%>','</em>','</a>','</a>', 430 '<ul class="dropdown-menu" role="menu" aria-labelledby="userInfoBox">', 431 '<li role="presentation">','<a role="menuitem" tabindex="-1" id="accountURI" href="<%=domain%>/auth/account/<%=_accountURI%>">','我的账户','</a>', '</li>', 432 '<li>', '<a role="menuitem" tabindex="-1" href="<%=domain%>/auth/msgManager/index" class="msg-link">','消息','(','<em>','</em>',')','</a>','</li>', 433 '<li>','<a role="menuitem" tabindex="-1" id="quit">','退出登录','</a>','</li>','</ul>'].join(''); 434 seajs.use("package/data", function(d) { 435 var obj = json.isJSON(d.uinfo) ? d.uinfo : {}; 436 that.uinfo(loginTmpl,obj); 437 }) 438 }, 439 uinfo: function(loginTmpl,obj){ 440 var conf = J.extend({ 441 domain: Domains.base, 442 }); 443 444 if (obj.loginFlag == 1) { 445 J.extend({ 446 _isShow: '', 447 _accountURI: '#', 448 _userName: 'hi!' + obj._userName, 449 _msgNum: obj._msgNum 450 },conf); 451 452 J("#homelogin").show(); 453 J("#homeunlogin").hide(); 454 if (conf._msgNum != 0) { 455 conf._isShow = 'display:"none"'; 456 } 457 if (obj._userType == 2) { 458 conf._accountURI = 'companyaccount_index'; 459 } else { 460 conf._accountURI = 'myaccount_index'; 461 } 462 var opts = { 463 container: '#homelogin', 464 tmpl: loginTmpl, 465 options: conf 466 }; 467 template.render(opts); 468 } else { 469 J("#homelogin").hide(); 470 J("#homeunlogin").show(); 471 } 472 }, 473 toTop: function(){ 474 J("#toTop").on('click', function() { 475 J('html,body').animate({ 476 scrollTop: 0 477 }, 700) 478 }); 479 J(window).scroll(function() { 480 var s = J(window).scrollTop(); 481 if (s > 600) { 482 J("#toTop").fadeIn(100) 483 } else { 484 J("#toTop").fadeOut(200) 485 } 486 }) 487 }, 488 _getCookieOpt: function(setting) { 489 setting = setting || {}; 490 var opt = { 491 domain: Domains.base, 492 expires: 60 * 60 * 24 * (setting.expires || 1), 493 path: '/' 494 }; 495 return opt; 496 }, 497 utm2cookie: function(opts){ 498 var conf = J.extend({ 499 utm_type: opts.utm_type, 500 utm_source: opts.utm_source, 501 utm_medium: opts.utm_medium, 502 utm_term: opts.utm_term, 503 utm_content: opts.utm_content, 504 utm_campaign: opts.utm_campaign, 505 setting: this._getCookieOpt({ 506 expires : 30 507 }) 508 },opts || {}); 509 510 if (conf.utm_type != 'null' && conf.utm_source != 'null') { 511 cookie('utm_type', parseInt(conf.utm_type), conf.setting); 512 cookie('utm_source', conf.utm_source, conf.setting); 513 cookie('utm_medium', conf.utm_medium, conf.setting); 514 cookie('utm_term', conf.utm_term, conf.setting); 515 cookie('utm_content', conf.utm_content, conf.setting); 516 cookie('utm_campaign', conf.utm_campaign, conf.setting); 517 } else { 518 return false; 519 } 520 }, 521 navActive:function(uri){ 522 var category = "", 523 pattern = /^http(s):\/\/.*\/.*\/(.*?)\/(.*?)\//g; 524 var mts = pattern.exec(uri); 525 if (mts != null) 526 { 527 var parent = mts[1]; 528 var child = mts[2]; 529 if (parent == 'aboutus'&& 'guidelinessecurityfriendlinks'.indexOf(child) < 0) { 530 category = parent + '>!gsf'; 531 } 532 else{ 533 category = parent + '>' + child; 534 } 535 } 536 537 switch(category){ 538 case 'aboutus>guidelines': 539 J('.navbar-nav li').removeClass('active'); 540 J('.navbar-nav').children('li').eq(3).addClass('active'); 541 break; 542 case 'aboutus>security': 543 J('.navbar-nav li').removeClass('active'); 544 J('.navbar-nav').children('li').eq(2).addClass('active'); 545 break; 546 case 'aboutus>friendlinks': 547 J('.navbar-nav li').removeClass('active'); 548 break; 549 case 'aboutus>!gsf'://!guidelines!security!friendlinks 550 J('.navbar-nav li').removeClass('active'); 551 J('#header .nav').children('li').eq(4).find('.dropdown-menu').remove(); 552 J('.navbar-nav').children('li').eq(4).addClass('active'); 553 break; 554 default: 555 J('.navbar-nav li').removeClass('active'); 556 J('.navbar-nav').children('li').eq(1).addClass('active') 557 break; 558 } 559 } 560 }; 561 return MOD; 562 }); 563 define.pack("./main", ["jquery","./request","./template","./browser","./domains", "./cookie", "./html", "./log", "./error", "./helper", "./response"], function(require, exports, module) { 564 var J = require("jquery"), 565 Module = module.constructor; 566 var DD = window.DD || {}; 567 DD.$ = DD.J = J; 568 DD.UI = DD.UI || {}; 569 DD.Module = DD.Module || {}; 570 DD.request=require("./request"); 571 DD.template = require("./template"); 572 DD.browser = require("./browser"); 573 DD.domains = require("./domains"); 574 DD.cookie = require("./cookie"); 575 DD.html = require("./html"); 576 DD.log = require("./log"); 577 DD.error = require("./error"); 578 DD.helper = require("./helper"); 579 DD.response = require("./response"); 580 DD.json = require("./json"); 581 DD.user = require("./user"); 582 return DD; 583 });
2. package/data.js (数据入口文件)
1 /** 2 * 数据入口文件 v20151022 3 */ 4 define(['dd','common/config/url'],function(require){ 5 var DD = require('dd'), 6 url = require('common/config/url'); 7 var MOD = { 8 cmsAC:function(conf){ 9 conf = conf || {}; 10 DD.request.get({ 11 url: url.cmsAC, 12 callback: { 13 success: conf.success //TODO:cache 14 } 15 }); 16 }, 17 cmsMR:function(conf){ 18 conf = conf || {}; 19 DD.request.get({ 20 url: url.cmsMR, 21 callback: { 22 success: conf.success //TODO:cache 23 } 24 }); 25 }, 26 getFPAndInv:function(conf){ 27 conf = conf || {}; 28 DD.request.get({ 29 url: url.getFPAndInv, 30 callback: { 31 success: conf.success //TODO:cache 32 } 33 }); 34 }, 35 logout:function(conf){ 36 conf = conf || {}; 37 DD.request.get({ 38 url: url.logout, 39 callback: { 40 success: conf.success //TODO:cache 41 } 42 }); 43 }, 44 uinfo:function(conf){ 45 conf = conf || {}; 46 DD.request.get({ 47 url: url.uinfo, 48 callback: { 49 success: conf.success //TODO:cache 50 } 51 }); 52 } 53 }; 54 return MOD; 55 });
3. template/tmpl_index.js (页面模板文件)
1 /** template|index|v20151027*/ 2 define(['package/main','common/util/utils'], function(require, exports, module) { 3 var DD = require("package/main"), 4 util = require("common/util/utils"); 5 var tmpl = { 6 'notice_tmpl': function(data) { 7 var __p = [], 8 _p = function(s) { 9 __p.push(s) 10 }; 11 with(data || {}) { 12 var list = data.arcitleList; 13 var len = list.length; 14 if (len > 3) { 15 len = 3; 16 } 17 for (var i = 0; i < len; i++) { 18 var ntitle = DD.html.htmlEncode(list[i].title).replace(/[ ]/g,""); 19 if (ntitle.length <= 0) continue; 20 __p.push('<li><a title="'); 21 _p(ntitle.replace('<br>', '')); 22 __p.push('" target=blank href="'); 23 _p(DD.domains.base); 24 __p.push('/cms/arcitleDetail?id='); 25 _p(list[i].id); 26 __p.push('&cateId=3">'); 27 _p(list[i].title.replace('<br>', '')+'</a>'); 28 if (list[i].isNew) { 29 __p.push('<i clannouncementListass="new-icon"></i>'); 30 } 31 __p.push('<span>'); 32 _p(util.date.format(list[i].createTime,'yyyy-MM-dd')); 33 __p.push('</span></li>'); 34 } 35 } 36 return __p.join(""); 37 }, 38 'media_tmpl': function(data) { 39 var __p = [], 40 _p = function(s) { 41 __p.push(s) 42 }; 43 with(data || {}) { 44 var list = data.arcitleList; 45 var len = (list.length >= 6) ? 6 : list.length; 46 for (var i = 0; i < len; i++) { 47 var ntitle = DD.html.htmlEncode(list[i].title).replace(/[ ]/g,""); 48 var titleSub = ""; 49 if (ntitle.length > 28) { 50 titleSub = ntitle.substr(0, 28) + "…" 51 } else { 52 titleSub = ntitle 53 } 54 __p.push('<li><a title="'); 55 _p(ntitle.replace('<br>', '')); 56 __p.push('" target=blank href="'); 57 _p(DD.domains.base); 58 __p.push('/cms/arcitleDetail?id='); 59 _p(list[i].id); 60 __p.push('&cateId=4">'); 61 _p(titleSub.replace('<br>', '')); 62 __p.push('</a></li>'); 63 } 64 } 65 return __p.join(""); 66 }, 67 'invest_list_tmpl': function(data) { 68 var __p = [], 69 _p = function(s) { 70 __p.push(s) 71 }; 72 with(data || {}) { 73 var list_bw=data.list_borrows; 74 var len=list_bw.length; 75 var repayType=["还款方式","等额本息","先息后本","本息一次","等额平息"]; 76 if (len > 5){ 77 len = 5; 78 } 79 for(var i = 0; i < len; i++){ 80 __p.push('<li id="tl00'); 81 _p(i); 82 __p.push('" class="hvr-sweep-to-top">'); 83 if(list_bw[i].isNew==1){ 84 __p.push('<div class="i_01 new"></div>'); 85 } 86 else{ 87 __p.push('<div class="i_01"></div>'); 88 } 89 __p.push('<div class="i_02"><img src="'); 90 _p(list_bw[i].img); 91 __p.push('" style="width:36px;height:30px;margin:0 15px 0 -52px;"><a href="'); 92 _p(DD.domains.base); 93 __p.push('/invest/prodetail_index?id='); 94 _p(list_bw[i].id); 95 __p.push('">'); 96 _p(list_bw[i].no); 97 __p.push('</a></div>'); 98 var num1=Number(list_bw[i].apr*100).toFixed(2); 99 __p.push('<div class="i_03">'); 100 _p(num1); 101 __p.push('%</div>'); 102 var dateName=""; 103 if(list_bw[i].isDayLoan==1){ 104 dateName="天" 105 }else{ 106 dateName="个月" 107 } 108 __p.push('<div class="i_04">'); 109 _p(list_bw[i].periods); 110 _p(dateName); 111 __p.push('</div><div class="i_05">'); 112 _p(repayType[list_bw[i].repayType]); 113 var amountForm=DD.helper.toThousands(list_bw[i].amount); 114 __p.push('</div><div class="i_06">'); 115 _p(amountForm); 116 __p.push('元</div><div class="i_07"><div class="index-progress" style="height: 46px;line-height: 45px;">'); 117 _p(list_bw[i].process); 118 __p.push('%</div></div>'); 119 var invaFlagStr=util.business.getInvesFlag(list_bw[i],"1"); 120 __p.push('<div class="i_08"><a href="'); 121 _p(DD.domains.base); 122 __p.push('/invest/prodetail_index?id='); 123 _p(list_bw[i].id); 124 if(list_bw[i].status == 2){ 125 __p.push('" class="disableFla">'); 126 } 127 else{ 128 __p.push('">'); 129 } 130 _p(invaFlagStr); 131 __p.push('</a></div>'); 132 } 133 } 134 return __p.join(""); 135 }, 136 'financial_plans_tmpl': function(data) { 137 data = data ||{} 138 var __p = [],timeId=data.id+"1",num1="", 139 _p = function(s) { 140 __p.push(s) 141 }; 142 __p.push('<p class="title">'); 143 _p(data.name); 144 __p.push('</p>'); 145 if(data.isNew == 1){ 146 __p.push('<em class="new-icon"></em>'); 147 } 148 if (!(data.addRate == undefined || data.addRate <= 0)) { 149 __p.push('<span class="perc" style="position: absolute;top: 63px;left: 162px;font-size: 18px;">+'); 150 _p(Number(data.addRate).toFixed(1)); 151 __p.push('%</span>'); 152 num1=Number(data.num-data.addRate).toFixed(1); 153 }else{ 154 num1=Number(data.num).toFixed(1); 155 } 156 __p.push('<span class="num">'); 157 _p(num1); 158 __p.push('</span><span class="perc">%</span><p class="rev">预期年化收益</p>'); 159 if(data.isShowTime){ 160 __p.push('<a class="ableFla" href="'); 161 }else{ 162 __p.push('<a class="disableFla" href="'); 163 } 164 _p(DD.domains.base);_p(data.toPage);__p.push('?id='); 165 _p(data.id);__p.push('">');_p(data.flagStr);__p.push('</a>'); 166 if(data.isShowTime){ 167 __p.push('<p class="time">剩余时间:<span id="'); 168 _p(timeId); 169 __p.push('></span></p>'); 170 }else{ 171 __p.push('<p class="notime"> </p>'); 172 } 173 return __p.join(""); 174 } 175 176 }; 177 return tmpl; 178 });
4. module/init.js (模块业务文件)
1 /*首页模块2|v2015-10-11*/ 2 (function() { 3 var mods = [], 4 version = parseFloat(seajs.version); 5 define(['jquery','dd','common/plugin/slides.min','template/tmpl_index','package/data','common/util/utils'],function(require, exports, module) { 6 var uri = module.uri || module.id, 7 m = uri.split("?")[0].match(/^(.+\/)([^\/]*?)(?:\.js)?.J/i), 8 root = m && m[1], 9 name = m && "./" + m[2].substring(0,m[2].length), 10 i = 0, 11 len = mods.length, 12 curr, args, undefined; 13 name = name.replace(/\.r[0-9]{15}/, ""); 14 for (; i < len; i++) { 15 args = mods[i]; 16 if (typeof args[0] === "string") { 17 name === args[0] && (curr = args[2]); 18 args[0] = root + args[0].replace("./", ""); 19 version > 1 && define.apply(this, args); 20 } 21 } 22 mods = []; 23 require.get = require; 24 return typeof curr === "function" ? curr.apply(this, arguments) : require; 25 }); 26 define.pack = function() { 27 mods.push(arguments); 28 version > 1 || define.apply(null, arguments) 29 } 30 })(); 31 define.pack("./animate",["jquery",'common/plugin/slides.min','dd'],function(require, exports, module){ 32 var J = require('jquery'), 33 animate = {}, 34 DD = require('dd'); 35 require('common/plugin/slides.min')(J); 36 animate.slider = function(opt){ 37 var conf = J.extend({ 38 container : opt.container, 39 auto : opt.auto || true, 40 nav : opt.nav || true, 41 pause: opt.pause || true, 42 speed : opt.speed || 300, 43 pager : opt.pager || true 44 }, opt || {}); 45 J(conf.container).responsiveSlides({ 46 auto : conf.auto, 47 nav : conf.nav, 48 pause: conf.pause, 49 speed : conf.speed, 50 pager : conf.pager 51 }); 52 }; 53 54 animate.announcement = function(opt){ 55 var conf = J.extend({ 56 container : opt.container, 57 _interval : opt.interval || 3000, 58 speed : opt.speed || 600, 59 }, opt || {}),_moving, 60 _wrap = J(opt.container); 61 _wrap.hover(function(){ 62 clearInterval(_moving); 63 },function(){ 64 _moving = setInterval(function(){ 65 var _field = _wrap.find("li:first"); 66 var _h = _field.height(); 67 _field.animate({marginTop:-_h+'px'},conf.speed,function(){ 68 _field.css('marginTop',0).appendTo(_wrap); 69 }) 70 },conf._interval) 71 }).trigger('mouseleave'); 72 }; 73 74 animate.bind = function(){ 75 //animatedcss类动画的初始定义,ie8不加载 76 if(DD.browser.isIE(8)){ //判断是否是IE/ 77 J(".callbacks1_s2").on('click',function(event){ 78 J(event).addClass("callbacks_here"); 79 }); 80 } 81 J('#financial .plans').on({ 82 'mouseover':function(){J(this).find('.time').show();}, 83 'mouseout':function(){J(this).find('.time').hide();} 84 }); 85 J('li.dropdown').on({ 86 'mouseover':function(){J(this).addClass('open');}, 87 'mouseout':function(){J(this).removeClass('open');} 88 }); 89 90 J('#userInfoBox').on({ 91 'mouseover':function(){J("#homelogin").addClass('open');}, 92 'mouseout':function(){J("#homelogin").removeClass('open');} 93 }); 94 95 J("#goInvest,#goAboutus,#_userName").on('click',function(){ 96 window.location.href=J(this).attr("href"); 97 }); 98 }; 99 100 animate.run = function(opts){ 101 animate.slider({container : opts[0]}); 102 animate.announcement({container : opts[1]}); 103 animate.bind(); 104 }; 105 106 return animate; 107 }); 108 define.pack("./render",["jquery",'dd','template/tmpl_index','package/data','common/util/utils'],function(require, exports, module){ 109 var J = require('jquery'), 110 indexTmpl = require('template/tmpl_index'), 111 util = require("common/util/utils"), 112 data = require('package/data'), 113 DD = require('dd'); 114 return { 115 ac: function(dom){ 116 data.cmsAC({ 117 success:function(data){ 118 var obj = DD.response(data); 119 var opts = { 120 container: dom, 121 tmpl: indexTmpl.notice_tmpl(DD.json.isJSON(obj) ? obj: {}), 122 options: {} 123 }; 124 DD.template.render(opts); 125 }}); 126 }, 127 mr: function(dom){ 128 data.cmsMR({ 129 success:function(data){ 130 var obj = DD.response(data); 131 var opts = { 132 container: dom, 133 tmpl: indexTmpl.media_tmpl(DD.json.isJSON(obj) ? obj : {}), 134 options: {} 135 }; 136 DD.template.render(opts); 137 }}); 138 }, 139 _invList: function(dom){ 140 data.getFPAndInv({ 141 success:function(data){ 142 var obj = DD.response(data); 143 var opts = { 144 container: dom, 145 tmpl: indexTmpl.invest_list_tmpl(DD.json.isJSON(obj) ? obj : {}), 146 options: {} 147 }; 148 DD.template.render(opts); 149 }}); 150 }, 151 _loadImg: function(dom){ 152 dom = dom instanceof jQuery ? dom : J(dom); 153 data.getFPAndInv({ 154 success:function(data){ 155 var obj = DD.response(data); 156 obj=DD.json.isJSON(obj) ? obj : {}; 157 for (i = 0; i < 5; i++) { 158 util.business.loadImg(obj.list_borrows[i].process,dom); 159 } 160 }}); 161 }, 162 _finPlan:{ 163 bind:function(type,obj){ 164 if(obj && ("" != obj) && ("undifinde" != obj)){ 165 var conf = { 166 num: obj.apr * 100, 167 flagStr: util.business.getInvesFlag(obj,"0"), 168 id: obj.id, 169 isNew: obj.isNew, 170 isShowTime: obj.status == 2 ? true : false, 171 addRate: obj.addRate * 100 172 }; 173 switch (type) { 174 case 0: 175 conf = J.extend({ 176 name: '活期宝', 177 toPage: '/invest/flex_borrow', 178 container: '#huoqibao' 179 },conf); 180 break; 181 case 1: 182 conf = J.extend({ 183 name: '3个月计划', 184 toPage: '/invest/optimise_borrow', 185 container: '#3yue' 186 },conf); 187 break; 188 case 2: 189 conf = J.extend({ 190 name: '6个月计划', 191 toPage: '/invest/optimise_borrow', 192 container: '#6yue' 193 },conf); 194 break; 195 case 3: 196 conf = J.extend({ 197 name: '12个月计划', 198 toPage: '/invest/optimise_borrow', 199 container: '#12yue' 200 },conf); 201 break; 202 default: 203 return false; 204 } 205 var opts = { 206 container: conf.container, 207 tmpl: indexTmpl.financial_plans_tmpl(conf), 208 options: {} 209 }; 210 J(opts.container).addClass("sa_top"); 211 DD.template.render(opts); 212 } 213 }, 214 show:function(){ 215 var self = this; 216 data.getFPAndInv({ 217 success:function(data){ 218 var obj = DD.response(data); 219 obj = DD.json.isJSON(obj) ? obj : {}; 220 self.bind(0,obj.flex_borrows[0]); 221 self.bind(1,obj.optimise1_borrows[0]); 222 self.bind(2,obj.optimise2_borrows[0]); 223 self.bind(3,obj.optimise3_borrows[0]); 224 }}); 225 } 226 }, 227 run:function(opts){ 228 this.ac(opts[0]); 229 this.mr(opts[1]); 230 this._finPlan.show(); 231 this._invList(opts[2]); 232 this._loadImg(opts[3]); 233 } 234 }; 235 236 }); 237 define.pack("./init",["jquery",'dd','common/util/utils'],function(require, exports, module){ 238 var J = require('jquery'), 239 util = require("common/util/utils"), 240 DD = require('dd'); 241 return { 242 init: function(options){ 243 var that = this; 244 var opts = J.extend({ 245 _amOpt: ['#slider','ul.announcements'], 246 _rdOpt: ['.announcements','#mediaReports','#investmentList','#tl000 .index-progress'] 247 }, options); 248 require.async('./animate', function(animate) { 249 animate.run(opts._amOpt); 250 }); 251 require.async('./render', function(render) { 252 render.run(opts._rdOpt); 253 }); 254 }, 255 time: util.business.showBorrowTime 256 }; 257 });
5. common/event.js (事件处理文件)
注:这里代码主要是自定义事件的,个人感觉JQuery封装的事件挺强大的,所以暂未使用,后期有好的思路需要重新写下
1 /** 2 * 事件处理 v20151027 3 */ 4 define(['lib/jquery'],function(require, exports, module) { 5 var $ = require('lib/jquery'); 6 exports.batchBind = function(dom, obj) { 7 for (var evt in obj) { 8 (function(evt, handlers) { 9 $(dom).bind(evt, function(e) { 10 var e = e || event; 11 var target = e 12 .target || e.srcElement; 13 for (var cls in handlers) { 14 if ($(target).hasClass(cls)) { 15 if (handlers[cls].call(target)) { 16 break; 17 } 18 } 19 } 20 }); 21 })(evt, obj[evt]); 22 } 23 }; 24 exports.enableCustomEvent = function(obj) { 25 $.extend(obj, { 26 addEvent: function(type, func) { 27 this._customEventListeners = this._customEventListeners || {}; 28 this._customEventListeners[type] = this._customEventListeners[type] || []; 29 this._customEventListeners[type].push(func); 30 return this; 31 }, 32 delEvent: function(type, func) { 33 var funcs = this._customEventListeners[type]; 34 if (funcs) { 35 for (var i = funcs.length - 1; i >= 0; i--) { 36 if (funcs[i] == func) { 37 funcs[i] = null; 38 break; 39 } 40 } 41 } 42 return this; 43 }, 44 fireEvent: function(type) { 45 if (!this._customEventListeners || !this._customEventListeners[type]) return; 46 var funcs = this._customEventListeners[type], 47 args = $.makeArray(arguments), 48 tmp = null, 49 returnValue = true; 50 args.shift(); 51 for (var i = 0, j = funcs.length; i < j; i++) { 52 if (funcs[i]) { 53 try { 54 tmp = funcs[i].apply(this, args); 55 if (tmp === false) { 56 returnValue = false; 57 } 58 } catch (ox) {} 59 } 60 } 61 return returnValue; 62 } 63 }); 64 return obj; 65 }; 66 });
6. ui/dialog.js (UI组件-弹窗 )
注:首页中未使用,需要根据网站弹窗样式功能修改
1 /**UI|Dialog|v20151029**/ 2 define("./dialog",["jquery","dd"],function(require, exports, module) { 3 var J = require('jquery'), 4 DD = require('dd'); 5 //require('./dialog.css'); //css 6 var jQuery, $; 7 jQuery = $ = J; 8 var _id = 0; 9 var Dialog = function(options) { 10 this.id = 'dialog_' + (++_id); 11 this.dom = null; 12 this.mask = null; 13 this.timer = null; 14 this.options = J.extend({ 15 title: options.title || '', 16 header: options.header || '', 17 footer: options.footer || '', 18 content: options.content || '', 19 submitButtonText: options.submitButtonText || '确定', 20 cancelButtonText: options.cancelButtonText || '取消', 21 dragable: options.dragable || true, //是否可以拖曳 22 destroyWhenClosed: options.destroyWhenClosed || true, 23 autoClose: options.autoClose || false, 24 autoCloseDelay: options.autoCloseDelay || 1500, 25 useModal: options.useModal || true, 26 closeAfterSubmit: options.closeAfterSubmit || true, 27 showCloseButton: options.showCloseButton || true, 28 showSubmitButton: options.showSubmitButton || true, 29 showCancelButton: options.showCancelButton || true, 30 showHeader: options.showHeader || true, 31 showFooter: options.showFooter || true, 32 onCreated: options.onCreated || null, 33 onOpened: options.onOpened || null, 34 onClosed: options.onClosed || null, 35 onDestroyed: options.onDestroyed || null, 36 onSubmitted: options.onSubmitted || null, 37 onCanceled: options.onCanceled || null, 38 realOnCanceled: options.realOnCanceled || null, 39 width: options.width || '350px', 40 height: options.height || 'auto', 41 zIndex: options.zIndex || 5000, 42 template: options.template || '', 43 autoPosit: options.autoPosit || true, 44 left: options.left || '25%', 45 top: options.top || '25%' 46 }, options || {}); 47 Dialog.instances[this.id] = this; 48 } 49 Dialog.prototype = { 50 create: function() { 51 var _this = this; 52 var tplData = {}; 53 tplData.id = this.id; 54 tplData.showHeader = this.options.showHeader ? '' : 'display:none;'; 55 tplData.showFooter = this.options.showFooter ? '' : 'display:none;'; 56 tplData.showCloseButton = this.options.showCloseButton ? '' : 'display:none;'; 57 tplData.showSubmitButton = this.options.showSubmitButton ? '' : 'display:none;'; 58 tplData.showCancelButton = this.options.showCancelButton ? '' : 'display:none;'; 59 tplData.header = this.options.header ? this.options.header : ''; 60 tplData.title = this.options.title ? this.options.title : ''; 61 tplData.footer = this.options.footer ? this.options.footer : ''; 62 tplData.content = this.options.content ? this.options.content : ''; 63 tplData = J.extend(this.options, tplData); 64 var dialog = DD.template.parse(this.options.template, tplData); 65 J(document.body).append(dialog); 66 if ($.browser.msie && !window.XMLHttpRequest) { 67 var divHeight = J('#' + this.id).height(); 68 $('#' + this.id).find(' > iframe').height(divHeight); 69 } 70 this.dom = J('#' + this.id).get(0); 71 J('#' + this.id + '_close').click(function() { 72 _this.options.onCanceled.call(_this); 73 _this.close(); 74 }); 75 J('#' + this.id + '_submit').click(function() { 76 if (_this.options.onSubmitted.call(_this) || _this.options.closeAfterSubmit) { 77 _this.close(); 78 } 79 }); 80 J('#' + this.id + '_cancel').click(function() { 81 _this.options.onCanceled.call(_this); 82 _this.options.realOnCanceled.call(this); 83 _this.close(); 84 }); 85 if (this.options.dragable) {} 86 if (this.options.useModal) { 87 this.mask = new Dialog.Mask({ 88 zIndex: this.options.zIndex - 1, 89 target: this.options.maskTarget 90 }); 91 this.mask.create(); 92 } 93 J('#' + this.id + ',#' + this.id + '_submit,#' + this.id + '_cancel,#' + this.id + '_close').attr('tabindex', 0); 94 this.options.onCreated.call(this); 95 }, 96 open: function() { 97 if (this.dom == null) { 98 this.create(); 99 } 100 if (this.options.autoPosit) { 101 var topPos = J(document).scrollTop() || 0, 102 win = window; 103 try { 104 while (win.frameElement) { 105 topPos += J(win.parent.document).scrollTop() || 0; 106 if (win.parent.$e) { 107 topPos -= win.parent.$e(win.frameElement).getXY()[1]; 108 } else if (win.parent.J) { 109 topPos -= win.parent.J(win.frameElement).offset().top; 110 } else { 111 break; 112 } 113 win = win.parent; 114 } 115 } catch (e) { 116 topPos = J(document).scrollTop() || 0, win = window; 117 } 118 if (this.options.vCenter) { 119 topPos = J(document).scrollTop() || 0 + ($(window).height() - $(this.dom).height()) / 2; 120 } 121 if (topPos < 0) { 122 topPos = 0; 123 } 124 J(this.dom).css({ 125 left: Math.floor((J(window).width() - J(this.dom).width()) / 2) + 'px', 126 top: this.options.vCenter ? topPos : 100 + topPos + 'px' 127 }); 128 } 129 J(this.dom).show().focus(); 130 var _this = this; 131 if (this.options.autoClose) { 132 if (this.timer) { 133 clearTimeout(this 134 .timer); 135 } 136 this.timer = setTimeout(function() { 137 _this.close(); 138 }, this.options.autoCloseDelay); 139 } 140 if (this.mask) { 141 this.mask.show(); 142 } 143 this.options.onOpened.call(this); 144 }, 145 close: function() { 146 J(this.dom).hide(); 147 if (this.mask) { 148 this.mask.hide(); 149 } 150 if (this.timer) { 151 clearTimeout(this.timer); 152 this.timer = null; 153 } 154 if (this.options && this.options.onClosed) { 155 this.options.onClosed.call(this); 156 } 157 if (this.options && this.options.destroyWhenClosed) { 158 var _this = this; 159 setTimeout(function() { 160 _this.destroy(); 161 }, 10); 162 } 163 }, 164 resize: function(size, resizeContent) { 165 if (resizeContent) { 166 var target = J('div.pop-common-bd', this 167 .dom); 168 } else { 169 var target = J(this.dom); 170 } 171 if (size.width) { 172 target.css({ 173 'width': size.width 174 }); 175 } 176 if (size.height) { 177 target.css({ 178 'height': size.height 179 }) 180 } 181 }, 182 changeButtonText: function(type, text) { 183 switch (type) { 184 case 'submit': 185 var btn = J('#' + this.id + '_submit').get(0); 186 break; 187 case 'cancel': 188 var btn = J('#' + this.id + '_cancel').get(0); 189 break; 190 } 191 btn.innerHTML = text; 192 }, 193 destroy: function() { 194 try { 195 J(this.dom).find('iframe').remove(); 196 J(this.dom).remove(); 197 if (this.mask) { 198 this.mask.destroy(); 199 } 200 this.options.onDestroyed.call(this); 201 this.dom = null; 202 this.options = null; 203 Dialog.instances[this.id] = null; 204 delete 205 Dialog.instances[this.id]; 206 } catch (ex) {} 207 } 208 }; 209 Dialog.template = ['<div id="<%=id%>" class="<%=mainStyle%>" style="position: absolute; z-index: <%=zIndex%>; top: <%=top%>; left: <%=left%>; height: <%=height%>; width: <%=width%>; display:none;">', 210 '<div class="py-pop-inner">', '<div class="pop-hd" id="<%=id%>_header" style="<%=showHeader%>" >', '<h3><%=title%></h3>', '</div>', '<div class="pop-bd"><%=content%></div>', 211 '<div class="pop-ft" id="<%=id%>_footer" style="<%=showFooter%>"><%=footer%><div class="pop-cmds"><a class="btn btn-green" style="<%=showSubmitButton%>" id="<%=id%>_submit" title="<%=submitButtonText%>"><b class="button"><span class="b-txt"><%=submitButtonText%></span></b></a><a title="<%=cancelButtonText%>" class="btn" style="<%=showCancelButton%>" id="<%=id%>_cancel"><b class="button"><span class="b-txt"><%=cancelButtonText%></span></b></a></div></div>', 212 '</div>', '<a id="<%=id%>_close" title="关闭对话框" href="#" class="close" style="<%=showCloseButton%>" onclick="return false;"><i class="icon i-pop-close"></i></a>', 213 '<iframe style="width: <%=width%>;" tabindex="-1" class="shade-ie6" frameborder="0" src="about:blank" scrolling="no"></iframe>', '</div>'].join(''); 214 Dialog.instances = {}; 215 Dialog.close = function(id) { 216 if (id) { 217 Dialog.instances[id].close(); 218 } else { 219 for (var ins in Dialog.instances) { 220 Dialog.instances[ins].close(); 221 } 222 } 223 } 224 Dialog.destroy = function() { 225 for (var ins in Dialog.instances) { 226 try { 227 Dialog.instances[ins].destroy(); 228 } catch (ex) {} 229 } 230 Dialog.instances = null; 231 } 232 Dialog.Mask = function(options) { 233 this.options = J.extend({ 234 target: window, 235 zIndex: 990, 236 opacity: 0 237 }, options || {}); 238 this.dom = null; 239 } 240 Dialog.Mask.prototype = { 241 create: function() { 242 var offset = this.getOffset(); 243 var width = J(this.options.target).width(), 244 height = J(this.options.target).height(), 245 zIndex = this.options.zIndex, 246 opacity = this.options.opacity; 247 this.dom = document.createElement('div'); 248 document.body.appendChild(this.dom); 249 J(this.dom).css({ 250 'position': 'absolute', 251 'zIndex': zIndex, 252 'left': offset.left + 'px', 253 'top': offset.top + 'px', 254 'width': width + 'px', 255 'height': height + 'px', 256 'display': 'none' 257 }); 258 J(this.dom).append('<div style="position:absolute; width:' + width + 'px;height:' + height + 'px; background:#000000;z-index:' + zIndex + ';opacity:' + opacity 259 + '; filter:alpha(opacity=' + (opacity * 100) + ');-moz-opacity:' + opacity + ';"></div>'); 260 if (jQuery.browser.msie) { 261 J(this.dom).append('<iframe style="opacity:0; filter:alpha(opacity=0);-moz-opacity:0;" scrolling="No" style="" border="0" frameborder="0" width="' + width + '" height="' + height + '"></iframe>'); 262 } else if (jQuery.browser.opera) { 263 J(this.dom).append('<img onmousedown="return false;" galleryimg="no" style="z-index:' + zIndex + '" width="' + width + '" height="' + height + '"/>'); 264 } 265 }, 266 show: function() { 267 if (!this.dom) { 268 this.create(); 269 } else { 270 var offset = this.getOffset(); 271 J(this.dom).css({ 272 'left': offset.left + 'px', 273 'top': offset.top + 'px' 274 }); 275 } 276 J(this.dom).show(); 277 }, 278 hide: function() { 279 J(this.dom).hide(); 280 }, 281 destroy: function() { 282 J(this.dom).remove(); 283 this 284 .dom = null; 285 this.options = null; 286 }, 287 getOffset: function() { 288 if (this.options.target == window || this.options.target == document) { 289 var offset = { 290 left: 0, 291 top: 0 292 }; 293 } else { 294 var offset = J(this.options.target).offset(); 295 } 296 var scrollTop = document.body.scrollTop || document.documentElement.scrollTop || 0; 297 offset.top += scrollTop; 298 return 299 offset; 300 } 301 } 302 Dialog.create = function(options) { 303 var that = this; 304 var opts = J.extend({}, options); 305 switch (options.type) { 306 case 'warn': 307 opts.title = options.title ? options.title : '温馨提示'; 308 opts.template = (Dialog.template || '').replace('<%=content%>', '<div class="xpy-media"><div class="img"><i class="ico-warn-20"></i></div><div class="txt ft-14"><%=content%></div></div>'); 309 break; 310 case 'error': 311 case 'notice': 312 opts.autoClose = true; 313 opts.useModal = false; 314 if (J('select').size()) { 315 opts.useModal = true; 316 } 317 opts.template = '<div id="<%=id%>" style="z-index:<%=zIndex%>" class="hint hint-blue"><div class="hint-inner"><i class="ico-hint ico-busy"></i><span class="hint-txt"><%=content%></span></div></div>'; 318 opts.content = options.content; 319 opts.zIndex = 9999; 320 break; 321 case 'verify': 322 options.content = options.content || ''; 323 opts.closeAfterSubmit = false; 324 opts.content = '<div class="pop-vcode">\ 325 <table>\ 326 <tbody>\ 327 <tr>\ 328 <td colspan="2"><span class="pop-vcode-tips">' + (options.subTitle || '请输入验证码') + '</span> <br/>' + options.content + '</td>\ 329 </tr>\ 330 <tr>\ 331 <td>验证码:</td>\ 332 <td>\ 333 <label accesskey="v"><input autocomplete="off" type="text" class="verifycode" name="verifycode_div" maxlength="6">不区分大小写</label>\ 334 </td>\ 335 </tr>\ 336 <tr>\ 337 <td></td>\ 338 <td>\ 339 <img height="53" width="130" src="http://' + (document.domain == 'qq.com' ? 'captcha.qq.com' : 'captcha.pengyou.com') + '/getimage?aid=15000901&' + Math.random() + '">\ 340 <a href="#" class="js_change" tabindex="-1" onclick="">看不清,换一张</a>\ 341 </td>\ 342 </tr>\ 343 </tbody>\ 344 </table>\ 345 </div>'; 346 opts.onOpened = function() { 347 var jqInput = J('input.verifycode', this.dom), 348 jqChange = J('a.js_change', this.dom); 349 if (!this.dom) { 350 return false; 351 }; 352 var dia = this; 353 jqInput.focus(); 354 jqChange.click(function() { 355 var url = 'http://' + (document.domain == 'qq.com' ? 'captcha.qq.com' : 'captcha.pengyou.com') + '/getimage?aid=15000901&' + Math.random(); 356 J(this).parent().find('img').attr('src', url); 357 jqInput.trigger('focus'); 358 return false; 359 }); 360 jqInput.unbind('keydown').bind('keydown', function(ev) { 361 var keycode = ev.keyCode, 362 subRS = false; 363 if (keycode === 13) { 364 ev.preventDefault(); 365 subRS = opts.onSubmitted.call(dia); 366 if (subRS || options 367 .closeAfterSubmit) { 368 dia.close(); 369 } 370 } 371 }); 372 }; 373 opts.onSubmitted = function() { 374 if (!this.dom) { 375 options.onSubmitted.call(this, ''); 376 if (that && that.close) { 377 that.close(); 378 } else { 379 Dialog.close(); 380 } 381 return false; 382 }; 383 var ipt = J('input.verifycode', this.dom), 384 code = ipt.val(); 385 if (/^\s*$/.test(code)) { 386 alert('请输入验证码'); 387 ipt.focus(); 388 return false; 389 } else { 390 options.onSubmitted.call(this, code); 391 return true; 392 } 393 }; 394 break; 395 case 'success': 396 opts.autoClose = true; 397 opts.useModal = false; 398 if (J('select').size()) { 399 opts.useModal = true; 400 } 401 opts.template = options.template; 402 opts.content = options.content; 403 opts.zIndex = 9999; 404 break; 405 } 406 return new Dialog(opts); 407 } 408 var DialogClass = { 409 open: function(type, content, config) { 410 var args = [].slice.apply(arguments); 411 config = args[args.length - 1]; 412 if ($.isPlainObject(config)) { 413 args.splice(-1, 1); 414 } else { 415 config = null; 416 } 417 if (args.length > 1) { 418 type = args[0]; 419 content = args[1]; 420 } else if (args.length === 1) { 421 type = null; 422 content = args[0]; 423 } else { 424 type = null; 425 content = ''; 426 } 427 var confDef = { 428 type: '', 429 title: '' 430 },dialog; 431 config = config ? $.extend(confDef, config) : confDef; 432 config.content = config.content || content; 433 config.type = config.type || type; 434 dialog = Dialog.create(config); 435 dialog.open(); 436 return dialog; 437 }, 438 closeAll: function() { 439 Dialog.close(); 440 }, 441 create: Dialog.create, 442 manager: Dialog 443 }; 444 return DialogClass; 445 });
7.index.jsp(页面文件-js部分)
1 <script type="text/javascript"> 2 ;(function () { 3 var fn = function () { 4 seajs.use(['package/main','jquery'],function(d,$){ 5 var href = window.location.href; 6 if(href&&href.indexOf('ddshenbian.com') > 0){ 7 d.user.navActive(href); 8 } 9 d.user.toTop(); 10 }); 11 }; 12 13 setTimeout(fn,0); 14 })(); 15 </script> 16 setTimeout(function () { 17 seajs.use('package/main', function(d){ 18 d.user.utm2cookie({ 19 utm_type: '<%=utm_type%>', 20 utm_source: '<%=utm_source%>', 21 utm_medium: '<%=utm_medium%>', 22 utm_term: '<%=utm_term%>', 23 utm_content: '<%=utm_content%>', 24 utm_campaign: '<%=utm_campaign%>' 25 }); 26 d.user.login(); 27 d.user.logout(); 28 }); 29 },1000); 30 var target=[],time_id =[]; 31 ;(function () { 32 window.onload = function () { 33 seajs.use(['lib/jquery','package/main'],function () { 34 seajs.use('module/index/init',function (i) { 35 i.init(); 36 setTimeout(function(){ 37 i.time(target,time_id); 38 }, 100); 39 }); 40 }); 41 }; 42 })();
下面看下页面效果:
存在问题
1.最明显会带来的问题就是请求增多,kissy这一方面做的很好,大多数的解决办法是需要运维去服务器做相关配置来实现
2.事件处理机制不太完善,目前还在学习中…
3.缓存处理、页面渲染等有待完善,请大神多多赐教