首先感谢huangzhir同学的小米抢购前端代码分析,我分析的代码也是从他那里拿的,这篇文章只想为自己留个备份,大家有兴趣也可以看一看,可能有些东西对你有所帮助也说不定。直接贴代码:
var isRollStatus = false, isPhone = false, isBox = false; (function() { m = { arrelems : [],//没用到 ready : null, doms : function() { var _this = this; var isReady = false; var readyList = []; var timer; _this.ready = function(fn) { if (isReady) { fn.call(document);//直接执行,这样就readyList没用了,所以readyList虽然是数组,但其实只会有一个函数元素。 } else { readyList.push(function() { return fn.call(this);//执行的时候this指向document。 }); }; return this; }; var onDOMReady = function() { for ( var i = 0x0; i < readyList.length; i++) { readyList[i].apply(document); }; readyList = null; }; var bindReady = function(evt) { if (isReady) {//因为IE6,IE7用到了setInterval,所以这里需要判断isReady的状态。 return; } isReady = true; onDOMReady.call(window);//直接调用onDOMReady()效果一样。 if (document.removeEventListener) { document.removeEventListener(_$[0], bindReady, false);//'DOMContentLoaded' } else if (document.attachEvent) { document.detachEvent(_$[1], bindReady);//'onreadystatechange' if (window == window.top) { clearInterval(timer); timer = null; } } }; /** * 监听document是否completely loaded and parsed,yes就call绑定函数bindReady。 * stylesheets loading会block绑定函数的执行,但图片不会。 * 这里用了三种方法hack不同的浏览器: * 1、IE9和Chrome,Firefox等主流浏览器:直接绑定DOMContentLoaded时间到document。 * 2、IE8:监听onreadystatechange事件并测试状态。 * 3、IE6,IE7:document.documentElement.doScroll('left')在ready之前会一直抛错。 */ if (document.addEventListener) {//IE9支持document.addEventListener方法 document.addEventListener(_$[2], bindReady, false);//'DOMContentLoaded' } else if (document.attachEvent) {//IE8 //https://developer.mozilla.org/en-US/docs/Web/Reference/Events/DOMContentLoaded document.attachEvent(_$[3], function() {//'onreadystatechange' if ((/loaded|complete/).test(document.readyState)) bindReady(); }); if (window == window.top) {//window == window.top是用来做什么的? timer = setInterval(function() {//IE6,IE7 try { isReady || document.documentElement.doScroll(_$[4]);//'left' } catch (e) { return } bindReady(); }, 0x5); } } }, $ : function() { return typeof arguments[0x0] === _$[5] ? document//'string' .getElementById(arguments[0x0]) : arguments[0x0]; }, extend : function(target, options) {//没用到 for (name in options) { target[name] = options[name]; } return target; }, cookie : function(key, value, options) { /** * 下面这段代码负责cookie的添加和删除, 在jquery.cookie.js中删除cookie有专门的方法removeCookie, * 小米在这里把添加和删除合并是为了简便起见。 * 不过话说String(value) !== _$[6]有什么用? */ if (arguments.length > 0x1 && String(value) !== _$[6]) {//6: '[object Object]' if (value === null || value === undefined) { options.expires = -0x1; }; if (typeof options.expires === _$[7]) {//'number' var days = options.expires, t = options.expires = new Date(); t.setDate(t.getDate() + days); }; value = String(value); return (document.cookie = [ encodeURIComponent(key), _$[8],//'=' options.raw ? value : encodeURIComponent(value), options.expires ? _$[9] + options.expires.toUTCString() : _$[10],//'; expires=',用的方法是UTC不是GMT。 options.path ? _$[11] + options.path : _$[12],//11: '; path=' options.domain ? _$[13] + options.domain : _$[14],//13: '; domain=' options.secure ? _$[15] : _$[16] ].join(_$[17]));//15: '; secure' }; /** * 这个判断同样没有意义,代码走到这里说明调用参数只有一个m.cookie(key)或者没有m.cookie(), * 所以value一定是undefined,直接写成options = {}就好了。 */ options = value || {}; //唉,options.raw! var result, decode = options.raw ? function(s) { return s; } : decodeURIComponent; return (result = new RegExp(_$[18] + encodeURIComponent(key)//'(?:^|; )' + key + '=([^;]*)' + _$[19]).exec(document.cookie)) ? decode(result[0x1]) : null; }, addEvent : (function() {//没用到 if (document.addEventListener) { return function(el, type, fn) { el.addEventListener(type, fn, false); }; } else { return function(el, type, fn) { el.attachEvent(_$[20] + type, function() {//'on' return fn.call(el, window.event);//window.event }); }; } })(), randomDiff : function(option) {//没用到 var paras = { randomS : 0x1, randomE : 0x5 }, options = m.extend(paras, option || {}), randomNum = Math .random() * (options.randomE - options.randomS + 0x1) + options.randomS; return parseInt(randomNum); }, getQueryString : function(name) {//没用到 var reg = new RegExp(_$[21] + name + _$[22], _$[23]);//'(^|&)', '=([^&]*)(&|$)', 'i' var r = window.location.search.substr(0x1).match(reg); if (r != null) return unescape(r[0x2]); return null; }, creatJs : function(src, elemid) { var Scrip = document.createElement(_$[24]);//'script' Scrip.src = src; if (!!elemid) { Scrip.id = elemid; if (m.$(elemid)) { document.body.removeChild(m.$(elemid)); } } document.body.appendChild(Scrip); }, /** * 如果有name='orgin'且value='mapp'的cookie就认为是用户从PC机登录,且删除该cookie并返回,否则就认为是Mobile登录, * 确认后跳转至Mobile登录页面。由此可猜测该cookie在用PC机登录小米首页的时候被创建了,但是Mobile登录时就没有创建或者值不同。 * @param url */ phone : function(url) { url = url || _$[25];//25: 'http://m.xiaomi.com' if (m.cookie(_$[26]) === _$[27]) {//26: 'orgin', 27: 'mapp' m.cookie(_$[28], null, {//'orgin' path : _$[29],//'/' domain : _$[30]//'.xiaomi.com' }); return }; var sUserAgent = navigator.userAgent; if (sUserAgent.indexOf(_$[31]) > -0x1//'Android' || sUserAgent.indexOf(_$[32]) > -0x1//'iPhone' || sUserAgent.indexOf(_$[33]) > -0x1//'iPod' || sUserAgent.indexOf(_$[34]) > -0x1) {//'Symbian' location.href = url; } }, init : function() { var _this = this; _this.doms(); } }; m.init(); })(); var json_1022 = {//这个数据是10月22号抢购的时候截取下来的,传递给hdcontrol的参数。 "stime": 1382414432,//server端的时间 "status": { "allow": false, "miphone": { "hdstart": true, "hdstop": false, "hdurl": "?_a=20131022_phone_df56ab516d&_op=choose", "duration": null, "pmstart": false }, "mibox": { "hdstart": true, "hdstop": false, "hdurl": "?_a=20131022_box_f9348273e1&_op=choose", "duration": null, "pmstart": false }, "mitv": { "hdstart": true, "hdstop": false, "hdurl": "?_a=20131022_mi_tv_ae3cc600f&_op=choose", "duration": null, "pmstart": false } } }; function hdcontrol(json) {//更新client和server的时间差;根据server给的状态位,显示当前手机和电视的购买情况(在售或已售完)。 var phonestart = json.status.miphone.hdstart, phonestop = json.status.miphone.hdstop, boxstart = json.status.mibox.hdstart, boxstop = json.status.mibox.hdstop; servertime = downServertime = json.stime; var diffTime = parseInt(servertime - miphoneBuy.localTime()); m.cookie(_$[35], diffTime, {//'xm_difft_hd' path : _$[36],//'/' domain : _$[37],//'.xiaomi.com' expires : 0x1//一天有效期 }); if (isRollStatus) {//点击购买窗口的购买按钮才会将isRollStatus置为true if (json.status.allow) {//购买成功? if (isPhone === true) {//你买的是手机吗? isPhone === false;//===应该是= if (json.status.miphone.hdurl == null || json.status.miphone.hdurl == _$[38]) {//'' window.location.reload(); } else { location.href = _$[39] + json.status.miphone.hdurl;//'http://t.hd.xiaomi.com/s/' + '?_a=20131022_phone_df56ab516d&_op=choose' } } else if (isBox === true) {//还是买的电视? isBox === false;//===应该是= if (json.status.mibox.hdurl == _$[40] || json.status.mibox.hdurl == null) {//'' window.location.reload(); } else { location.href = _$[41] + json.status.mibox.hdurl;//'http://t.hd.xiaomi.com/s/' + '?_a=20131022_box_f9348273e1&_op=choose' } } } isRollStatus = false; } if (phonestart === true && phonestop === false && boxstart === false && boxstop === true) { m.cookie(_$[42], 0x1, {//'xm_xt_obox' path : _$[43],//'/' domain : _$[44],//'.xiaomi.com' expires : 0x1 }); m.cookie(_$[45], null, {//'xm_xt_ophone' path : _$[46],//'/' domain : _$[47]//'.xiaomi.com' }); miphoneBuy.box(false); stepHtml.five(); } if (phonestart === false && phonestop === true && boxstart === true && boxstop === false) { m.cookie(_$[48], 0x1, {//'xm_xt_ophone' path : _$[49], domain : _$[50], expires : 0x1 }); m.cookie(_$[51], null, {//'xm_xt_obox' path : _$[52], domain : _$[53] }); miphoneBuy.box(false); stepHtml.six(); } if (phonestart === false && phonestop === true && boxstart === false && boxstop === true) { m.cookie(_$[54], 0x1, {//'xm_xt_pre' path : _$[55], domain : _$[56], expires : 0x1 }); m.cookie(_$[57], null, {//'xm_xt_obox' path : _$[58], domain : _$[59] }); m.cookie(_$[60], null, {//'xm_xt_ophone' path : _$[61], domain : _$[62] }); miphoneBuy.saleOut(); } }; var miphoneBuy = { localTime : function() {//取client端时间,单位是秒 return parseInt(new Date().getTime() / 0x3e8); }, jsonInter : function() {//从server取数据并回调hdcontrol函数 var timestamp = new Date().getTime();//这里的时间取的是本地时间戳 m.creatJs(_$[63] + timestamp, _$[64]);//63: 'http://tc.hd.xiaomi.com/hdget?callback=hdcontrol&_=', 64: 'jsonp' }, checkCookie : function() { var _this = this; if (m.cookie(_$[65])) {//'xm_xt_pre' _this.saleOut();//对哟,你来的太晚,已全部售完,我的心你不明白--《你把我灌醉》 } else { if (!m.cookie(_$[66])) {//'xm_difft_hd' _this.jsonInter();//这里主要用来取client和server的时间差 } setTimeout(function() { servertime = downServertime = miphoneBuy.localTime() + parseInt(m.cookie(_$[67]));//'xm_difft_hd',重算一下servertime和downServertime _this.jugeStatus(); }, 0x64);//留一点时间给jsonInter加载js文件和执行 } }, saleOut : function() {//全部已售完 if (window.timeInter) {//全没了,通知广大用户这一噩耗,定时器?也不用了! clearInterval(timeInter); } stepHtml.four(); miphoneBuy.box(false); }, jugeStatus : function() {//更新时间节点和页面状态 var _this = this; _this.timeNode(); timeInter = window.setInterval(function() { _this.timeNode(); servertime++; }, 0x3e8);//1000ms }, configs : { startDate : new Date(_$[68]).getTime(),//'10/15/2013 12:00:00' preLogMin : 0x1e//30 mins }, timeNode : function() { var _this = this; var nowTime = servertime * 0x3e8, startTime = _this.configs.startDate, preLogTime = startTime - _this.configs.preLogMin * 0xea60; if (m.cookie(_$[69])) {//'xm_xt_pre' _this.saleOut(); return } if (m.cookie(_$[70])) {//'xm_difft_hd' downServertime = miphoneBuy.localTime() + parseInt(m.cookie(_$[71]));//'xm_difft_hd' } //更新页面信息用的是servertime,而且是以ms为单位;更新倒计时窗口用的是downServertime; if (nowTime < preLogTime) {//未进入30分钟倒计时 stepHtml.one(); _this.timeOut(); } else if (nowTime >= preLogTime && nowTime < startTime) {//进入倒计时但尚未开始,提醒用户先登录 stepHtml.two(); _this.timeOut(); } else if (nowTime >= startTime) {//已经开售,正式拉开抢购大幕 if (m.cookie(_$[72])) {//'xm_xt_obox' stepHtml.five(); } else if (m.cookie(_$[73])) {//'xm_xt_ophone' stepHtml.six(); } else { stepHtml.three(); } } }, timeOut : function() { var _this = this; _this.SetRemainTime(); if (window.InterValObj) { clearInterval(InterValObj); } /** * 这一个InterValObj定时器用的多余,因为在抢购开始之前timeNode方法本身就会被每秒执行一次, * 于是timeOut也会被每秒执行一次,这里InterValObj相关的代码可以全部去掉,效果一样! */ InterValObj = window.setInterval(function() { _this.SetRemainTime(); }, 0x3e8); }, SetRemainTime : function() {//更新页面倒计时按钮的时间信息,提醒用户抢购什么时候开始。 var _this = this, endtime = _this.configs.startDate, setEndtime = endtime / 0x3e8; surplusTime = setEndtime - downServertime; if (surplusTime >= 0x0) { var second = Math.floor(surplusTime % 0x3c), minite = Math .floor((surplusTime / 0x3c) % 0x3c), hour = Math .floor((surplusTime / 0xe10) % 0x18), day = Math .floor((surplusTime / 0x15180) % 0x1e); downServertime++; var timeArray = [ second.toString(), minite.toString(), hour.toString(), day.toString() ]; var timeText = _$[74] + timeArray[0x2] + _$[75] + timeArray[0x1]//几小时几分几秒后开始 + _$[76] + timeArray[0x0] + _$[77]; if (hour === 0x0) { timeText = _$[78] + timeArray[0x1] + _$[79] + timeArray[0x0]//几分几秒后开始 + _$[80]; if (minite === 0x0) { timeText = _$[81] + timeArray[0x0] + _$[82];//几秒后开始 } } if (!!m.$(_$[83])) {//'surTime',倒计时窗口ID m.$(_$[84]).innerHTML = timeText;//'surTime' } } else { if (window.InterValObj) { clearInterval(InterValObj); } } }, box : function(bool) {//true: 打开购买窗口,false:关闭购买窗口 if (bool) { var mboxbg = m.$(_$[85]);//'boxbg' var mbox = m.$(_$[86]);//'box' mboxbg.style.height = Math.max( document.documentElement.clientHeight, document.documentElement.scrollHeight) + _$[87];//'px' mboxbg.style.display = _$[88];//'block' mbox.style.display = _$[89];//'block' } else {//关闭购买窗口;disable购买按钮并update显示文本为倒计时状态;重置倒计时的读秒 var mboxbg = m.$(_$[90]);//'boxbg',遮罩层 var mbox = m.$(_$[91]);//'box',弹出的购买窗口 mboxbg.style.display = _$[92];//'none' mbox.style.display = _$[93];//'none' if (window.rollInter) { clearInterval(rollInter); } Util.retime();//下面的count变量已经被重置 m.$(_$[94]).innerHTML = _$[95] + count + _$[96];//94: 'reback', 95: '重新进入(<span id=\'initCount\'>', 96: '</span>)' } }, init : function(option) { var _this = this; _this.checkCookie(); } }; var stepHtml = {//, /** * 购买手机:showBox('phone');购买电视:showBox('box') * 凡是带有"购买"字样的都是调用showBox,其他的"查询"和"支付"都是超链接 */ one : function() {//即将开始 var mhtml = stepHtml.htmlString(); m.$(_$[97]).innerHTML = mhtml.btn[0x0];//_$[141]: '<span class="untime"><label id="surTime" class="unbtn"></label></span>' m.$(_$[98]).innerHTML = mhtml.subTitle[0x0];//_$[147]: '' m.$(_$[99]).innerHTML = mhtml.lnks[0x0];//_$[156]: '手机预约查询&电视预约查询' m.$(_$[100]).innerHTML = mhtml.phonebtn[0x0];//_$[161]: '<span>1999元(16GB)</span>即将开始' m.$(_$[101]).innerHTML = mhtml.tvbtn[0x0];//_$[164]: '<span>2999元</span>即将开始' m.$(_$[102]).innerHTML = mhtml.msg[0x0];//_$[151]: '' m.$(_$[103]).innerHTML = mhtml.bottombtn[0x0];//_$[167]: '<label class="btn unbtn">即将开始</label>' }, two : function() {//即将开始,提醒用户先登录 var mhtml = stepHtml.htmlString(); var miID = (m.cookie(_$[104]));//'userId' if (miID) { m.$(_$[105]).innerHTML = mhtml.btn[0x0];//_$[141]: '<span class="untime"><label id="surTime" class="unbtn"></label></span>' } else { m.$(_$[106]).innerHTML = mhtml.btn[0x1];//_$[141]: '<a>提前登录</a>' } m.$(_$[107]).innerHTML = mhtml.lnks[0x0];//_$[156]: '手机预约查询&电视预约查询' m.$(_$[108]).innerHTML = mhtml.subTitle[0x0];//_$[147]: '' m.$(_$[109]).innerHTML = mhtml.phonebtn[0x0];//_$[161]: '<span>1999元(16GB)</span>即将开始' m.$(_$[110]).innerHTML = mhtml.tvbtn[0x0];//_$[164]: '<span>2999元</span>即将开始' m.$(_$[111]).innerHTML = mhtml.msg[0x0];//_$[151]: '' m.$(_$[112]).innerHTML = mhtml.bottombtn[0x0];//_$[167]: '<label class="btn unbtn">即将开始</label>' }, three : function() {//小米手机3和小米电视均可购买 var mhtml = stepHtml.htmlString(); m.$(_$[113]).innerHTML = mhtml.btn[0x2];//_$[143]: '购买手机&购买电视' m.$(_$[114]).innerHTML = mhtml.subTitle[0x0];//_$[147]: '' m.$(_$[115]).innerHTML = mhtml.phonebtn[0x1];//_$[162]: '<span>1999元(16GB)</span>立即购买' m.$(_$[116]).innerHTML = mhtml.tvbtn[0x1];//_$[165]: '<span>2999元</span>立即购买' m.$(_$[117]).innerHTML = mhtml.msg[0x4];//_$[155]: '购机成功用户请在3小时内下单,3小时内支付。支付手机&支付电视' m.$(_$[118]).innerHTML = mhtml.lnks[0x0];//_$[156]: '手机预约查询&电视预约查询' m.$(_$[119]).innerHTML = mhtml.bottombtn[0x1];//_$[168]: '购买手机' }, four : function() {//全部小米手机3及小米电视已售罄 var mhtml = stepHtml.htmlString(); m.$(_$[120]).innerHTML = mhtml.btn[0x3];//_$[144]: '支付手机&支付电视' m.$(_$[121]).innerHTML = mhtml.phonebtn[0x2];//_$[163]: '<span>1999元(16GB)</span>立即支付' m.$(_$[122]).innerHTML = mhtml.tvbtn[0x2];//_$[166]: '<span>2999元</span>立即支付' m.$(_$[123]).innerHTML = mhtml.subTitle[0x3];//_$[150]: '全部小米手机3及小米电视已售罄' m.$(_$[124]).innerHTML = mhtml.msg[0x3];//_$[154]: '购机成功用户请在3小时内下单,3小时内支付。' m.$(_$[125]).innerHTML = mhtml.lnks[0x3];//_$[159]: '手机购买查询&电视购买查询' m.$(_$[126]).innerHTML = mhtml.bottombtn[0x2];//_$[169]: '支付手机' }, five : function() {//小米电视已售罄,您可继续购买小米手机3 var mhtml = stepHtml.htmlString(); m.$(_$[127]).innerHTML = mhtml.btn[0x4];//_$[145]: '购买手机&支付电视' m.$(_$[128]).innerHTML = mhtml.phonebtn[0x1];//_$[162]: '<span>1999元(16GB)</span>立即购买' m.$(_$[129]).innerHTML = mhtml.subTitle[0x2];//_$[149]: '小米电视已售罄,您可继续购买小米手机3' m.$(_$[130]).innerHTML = mhtml.tvbtn[0x2];//_$[166]: '<span>2999元</span>立即支付' m.$(_$[131]).innerHTML = mhtml.msg[0x1];//_$[152]: '购机成功用户请在3小时内下单,3小时内支付。<a>支付手机</a>' m.$(_$[132]).innerHTML = mhtml.lnks[0x1];//_$[157]: '手机预约查询&电视购买查询' m.$(_$[133]).innerHTML = mhtml.bottombtn[0x1];//_$[168]: '购买手机' }, six : function() {//小米手机3已售罄,您可继续购买小米电视 var mhtml = stepHtml.htmlString(); m.$(_$[134]).innerHTML = mhtml.btn[0x5];//_$[146]: '购买电视&购买电视' m.$(_$[135]).innerHTML = mhtml.phonebtn[0x2];//_$[163]: '<span>1999元(16GB)</span>立即支付' m.$(_$[136]).innerHTML = mhtml.subTitle[0x1];//_$[148]: '小米手机3已售罄,您可继续购买小米电视' m.$(_$[137]).innerHTML = mhtml.tvbtn[0x1];//_$[165]: '<span>2999元</span>立即购买' m.$(_$[138]).innerHTML = mhtml.msg[0x2];//_$[153]: '购机成功用户请在3小时内下单,3小时内支付。<a>支付电视</a>' m.$(_$[139]).innerHTML = mhtml.lnks[0x2];//_$[158]: '手机购买查询&电视预约查询' m.$(_$[140]).innerHTML = mhtml.bottombtn[0x2];//_$[168]: '支付手机' }, htmlString : function() { var htmlSum = { btn : [ _$[141], _$[142], _$[143], _$[144], _$[145], _$[146] ],//hdBtns subTitle : [ _$[147], _$[148], _$[149], _$[150], ],//hdSubTitle msg : [ _$[151], _$[152], _$[153], _$[154], _$[155] ],//hdMsg lnks : [ _$[156], _$[157], _$[158], _$[159], _$[160], ],//hdLnks phonebtn : [ _$[161], _$[162], _$[163] ],//miphone tvbtn : [ _$[164], _$[165], _$[166] ],//mitv bottombtn : [ _$[167], _$[168], _$[169] ]//bottombtn }; return htmlSum; } }; var randomCount = parseInt(Math.random() * (0xa - 0x5 + 0x1) + 0x5), count = randomCount, CONFIG = { count : randomCount }, Util = { time : function() { var b = m.$(_$[170]);//'reback',<a id="reback" class="reback_btn_next">进入活动</a> if (count === 0x0) { b.innerHTML = _$[171];//'进入活动' b.className = _$[172];//'reback_btn_next' this.start(); return false; } count = count - 0x1; //只需要更新initCount元素的文本就好了,没必要更新reback的html b.innerHTML = _$[173] + count + _$[174];//173: '重新进入(<span id=\'initCount\'>', 174: '</span>)' }, start : function() { var me = this, reback = m.$(_$[175]);//'reback' reback.onclick = function() { /** * 向server发送请求,根据返回状态判断是否抢购成功; * Disable购买按钮; * 注意此时rollInter并没有被清除,也就是说从购买按钮已经可以点击到你真正点击的这段时间内Util.time一直 * 在执行,这里最好把rollInter清除掉。 */ isRollStatus = true;//开始尝试购买,抢购进入高潮! miphoneBuy.jsonInter(); me.retime(); reback.onclick = null; return false; }; }, retime : function() {//重置购买按钮为disable状态;重置倒计时读秒。 m.$(_$[176]).className = _$[177];//176: 'reback', 177: 'reback_btn' count = CONFIG.count; } }; var loginInfo = { data : { userId : 0x0, userName : _$[178]//'' }, init : function() { this.data.userId = m.cookie(_$[179]);//'userId' if (!this.data.userId) return false; //这里this.data.userId已经是true了,所以this.data.userName一定被赋值为m.cookie('XM_' + this.data.userId + '_UN') this.data.userName = (this.data.userId) ? m.cookie(_$[180]//'XM_' + this.data.userId + _$[181]) : _$[182];//181: '_UN', 182: '' if (this.data.userName == null || this.data.userName == _$[183]) {//'' var script = document.createElement(_$[184]);//'script' //185: 'https://account.xiaomi.com/pass/userInfoJsonP?userId=', 186: '&callback=loginInfo.getAccountInfo' script.src = _$[185] + this.data.userId + _$[186]; script.type = _$[187];//'text/javascript' script.async = true;//http://www.w3schools.com/tags/att_script_async.asp document.getElementsByTagName(_$[188])[0x0].appendChild(script);//'head' } else { this.upUserInfo(); } }, upUserInfo : function() { var nickName = this.data.userName; if (!!m.$(_$[189])) {//'LoginArea' //'LoginArea', '欢迎您 ', '!<a href=\'http://order.xiaomi.com/site/logout\'>退出</a>' m.$(_$[190]).innerHTML = _$[191] + nickName + _$[192]; m.$(_$[193]).style.paddingLeft = _$[194];//'LoginArea', '12px' } }, // { // "uniqName": "暗影萨满", // "miliaoInfo": { // "icon": "", // "nickName": "暗影萨满" // }, // "EM": { // "binded": true, // "address": "暗影萨满@dota.com" // }, // "PH": { // "binded": true, // "address": "186********" // }, // "userId": 28****** // } getAccountInfo : function(data) { if (data.userId) { this.data.userName = (data.uniqName) ? data.uniqName : data.userId; var option = { path : _$[195],//'/' domain : _$[196]//'.xiaomi.com' }; m.cookie(_$[197] + this.data.userId + _$[198], this.data.userName, option);//'XM_', '_UN' this.upUserInfo(); } } }; function showBox(gtype) { if (m.cookie(_$[199])) {//'userId' if (gtype === _$[200]) {//'phone' isPhone = true; } else if (gtype === _$[201]) {//'box' isBox = true; } miphoneBuy.box(true); m.$(_$[202]).innerHTML = CONFIG.count;//'initCount',重置购买窗口的购买按钮的倒计时读秒 rollInter = window.setInterval(_$[203], 0x3e8);//'Util.time()',每秒执行一次 } else { location.href = _$[204]; } }; m.ready(function() { m.phone(_$[205]);//'http://p.www.xiaomi.com/m/zt/open/index.html' miphoneBuy.init(); loginInfo.init(); });
第一步: 把超长的数组_$解码出来
我的办法是把它遍历出来之后放到textarea中,之后复制出来就好了,下面的sce.js只包含_$数组:
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <script type="text/javascript" src="sce.js"></script> </head> <textarea id="pp" cols="150" rows="30"></textarea> <script type="text/javascript"> for (var o in _$) { document.getElementById("pp").innerHTML += "'" + _$[o].replace(/'/g, "\\'") + "\',//" + o + "\n"; } </script> </html>
第二步:分析代码的执行顺序和功能
执行顺序如下,功能细节见代码:
- m.init() >> m.doms()
- bindReady() >> onDOMReady()
- m.phone()
- miphoneBuy.init() >> miphoneBuy.checkCookie() >> miphoneBuy.jugeStatus(),此时开始启动定时器timeInter,每秒调用一次timeNode,直至全部售完,抢购结束!
- loginInfo.init()
cookie的作用如下:
- 'xm_xt_obox' ,电视已售完
- 'xm_xt_obox' ,电视已售完
- 'xm_xt_pre' ,全部售完
- 'xm_difft_hd',client和server时间差
- 'orgin' == 'mapp',PC机登陆,否则认为是Mobile登陆
That‘s it.
相关推荐
在本文中,我们将深入探讨“享受代码的快乐--小米抢购前端代码分析”这一主题,主要涉及源码解析和工具应用。通过分析博主黄之锐在iteye博客上分享的文章,我们可以了解到小米抢购页面的前端实现细节以及相关技术的...
在本项目中,我们主要关注的是“仿小米官网首页2021最新版本前端代码”。这个项目提供了构建一个与小米官网2021年最新设计风格相似的前端页面所需的所有资源,包括HTML、CSS和JavaScript文件。让我们逐一深入探讨...
除此之外,小米官网的前端代码可能还涉及到其他技术,如: - SEO优化:通过元标签(meta tags)和语义化HTML提高搜索引擎可见性。 - AJAX调用API:与后端服务器通信,获取产品信息、评论等实时数据。 - Web字体:...
小米抢购源代码, using System; using System.Threading.Tasks; using System.Windows.Forms; using System.Timers; using Newtonsoft.Json; using System.Text.RegularExpressions; using System.Configuration; ...
总之,通过分析小米官网的源代码,我们可以学习到前端开发的最新趋势和技术实践,包括但不限于前端框架的应用、响应式设计、性能优化、安全防护和SEO策略等。这对于提升自己的前端技能、了解行业标准以及解决实际...
对于小米抢购页面的JS代码,混淆可能是为了防止恶意用户分析和利用抢购逻辑。 要对混淆的JS代码进行反混淆,我们需要遵循以下步骤: 1. **代码解析**:使用JavaScript解析库,如Esprima,将混淆的JS代码转化为抽象...
本文将详细解析“仿小米商城前端模板源码”的相关知识点,该源码是一个适用于手机分类商城的小程序前端项目,包含了9个主要页面,涵盖了用户在购物过程中可能涉及到的各种功能。 首先,我们要理解“前端”这一概念...
本资源完整还原小米官网静态页面,包含html,css以及页面包含的所有图片及字体,字体符号使用方法,请参考阿里巴巴矢量图库官网:https://www.iconfont.cn/。效果预览链接:...
还可以使用JavaScript库和框架,如jQuery简化DOM操作,React或Vue.js构建组件化、状态管理更高效的前端应用。 在实际开发过程中,我们还需要考虑到SEO(搜索引擎优化),确保HTML标签的合理使用以便搜索引擎理解...
【小米产品抢购软件】是一种专门针对小米公司热门产品的在线抢购辅助工具,它旨在帮助用户提高购买小米手机、智能设备等热门商品的成功率。在众多消费者对小米新品的追捧中,由于库存有限,抢购变得极具竞争性,而这...
压缩包内的文件名“极致-10月22日,小米手机3、小米电视、小米手机2S、小米盒子、红米手机发售.htm”可能是抢购活动的页面存档,可能包含了页面结构、脚本以及抢购时的具体交互逻辑。研究者可能通过分析这个页面的...
在本项目中,“前端项目——小米官网首页”旨在模拟实现小米官网的主页,采用的是基础的HTML、CSS技术,特别强调了对div和css的运用。这个项目对于初学者来说是一个很好的实践机会,因为它不涉及复杂的JavaScript...
微信小程序 商城模板 小米商城 (源代码+截图)微信小程序 商城模板 小米商城 (源代码+截图)微信小程序 商城模板 小米商城 (源代码+截图)微信小程序 商城模板 小米商城 (源代码+截图)微信小程序 商城模板 小米...
本文将深入探讨标题为"xiaomi.zip_c# 抢购_小米手机抢购_小米电视_抢购_抢购 c++"的项目,它涉及到使用C#语言开发的抢购器,专门针对小米手机和电视等产品。 首先,我们要理解的是C#(读作"C sharp")是一种面向...
10. **XHTML**: XHTML是HTML与XML的结合体,要求语法更加严格,但现代浏览器通常能很好地解析HTML5语法。 以上是构建小米商城注册和登录页面时可能会涉及的一些HTML知识点。实际开发中,可能还需要结合JavaScript...
【压缩包子文件的文件名称列表】:“小米商城(自行解压)”说明压缩包内包含了整个项目的源代码文件、图片资源和其他可能的素材。解压后,我们可以期待找到以下几类文件: 1. HTML文件:这些文件包含网页的结构,...
【网页前端项目小米商城源码】是一个用于学习和实践网页设计的开源项目,它复现了小米商城的主页面,提供了基础的用户交互和布局展示。这个项目可以帮助开发者理解和掌握前端开发的基本技能,包括HTML、CSS、...
圣道小米抢购软件是一款免费高效的小米抢购秒杀工具。软件采用P2P加速技术,抢购更迅速,更稳定,更高速,更高效。软件绿色便捷,永久免费,是小米抢购神器。 圣道小米抢购软件 功能特点 1.高速抢购 P2P加速技术,...