首先感谢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.
8170

被折叠的 条评论
为什么被折叠?



