Skip to content

Instantly share code, notes, and snippets.

@czy88840616
Created March 20, 2012 05:53
Show Gist options
  • Save czy88840616/2131810 to your computer and use it in GitHub Desktop.
Save czy88840616/2131810 to your computer and use it in GitHub Desktop.
paimai
/*ucool filePath=http://10.249.196.92:80/apps/auctionplatform/20111110/channel/pub/tiantian/tiantian.js?env=daily*/
/**
* @fileoverview 拍卖计时器
* @author 易敛<yilian.wj@taobao.com>
* @date 12-1-8
*/
KISSY.add('Countdown', function(S, DOM, Switch) {
var api = 'http://paimai.taobao.com/json/get_legacy_auction.htm?';
function Countdown(container, config) {
var cfg = {};
this.container = container;
this.config = S.merge(cfg, config);
this.itemList = [],this.overList = [],
this._init();
}
S.augment(Countdown, S.EventTarget, {
timer: function(){
var self = this, itemList = self.itemList, overList = self.overList, start = self.start,_timer,EVT_PAINT_OVER = 'paintOver';
var oTimeEvt = S.merge({}, S.EventTarget);
//计算剩余时间
function getLeftTime(remain) {
var now = + new Date();
return remain - (now - start);
}
var rePaintTimeDom = function(node, remain) {
var hourEl = DOM.get('input.hour',node), minEl = DOM.get('input.min',node), secEl = DOM.get('input.sec',node);
remain = self._timeSplit(getLeftTime(remain));
if (!remain) {
return false;
}
DOM.val(hourEl, remain.h);
DOM.val(minEl, remain.m);
DOM.val(secEl, remain.s);
return true;
};
function _repaint() {
if (itemList.length === 0) {
// this.stop();
_timer && clearTimeout(_timer);
return;
}
for (var i = 0; i < itemList.length;i++) {
var oItem = itemList[i], node = oItem[0], data = oItem[1], leftTime = data.leftTime,
end = data.end, timeToStart = data.timeToStart,start = data.start,status;
if (timeToStart > 0) {
status = rePaintTimeDom(node, timeToStart);
if (!status) {
oTimeEvt.fire(EVT_PAINT_OVER, {isStart:true,nodeIndex:i});
}
}
else {
status = rePaintTimeDom(node, leftTime);
if(!status){
oTimeEvt.fire(EVT_PAINT_OVER,{isOver:true,nodeIndex: i,end:end});
}
}
}
_timer = setTimeout(_repaint, 1000); //循环调用本方法开始倒计时
}
return {
/*
* 添加需要计时的item,
* oItem:[node,data] Array
* node: htmlElement, data:回传回来的参数
* */
add: function(oItem) {
itemList.push(oItem);
},
addOver: function(oItem){
overList.push(oItem);
},
run : function() {
_repaint();
},
stop: function() {
_timer && clearTimeout(_timer);
},
onStop: function() {
var remove = function(oStopItem) {
var i = S.indexOf(oStopItem, itemList);
if (i !== -1) {
itemList.splice(i, 1);
}
};
oTimeEvt.on(EVT_PAINT_OVER, function(ev) {
var oItem, node, data, leftTime,
template = '{h}点{m}分{s}秒';
if(ev.isStart){
oItem = itemList[ev.nodeIndex], node = oItem[0], data = oItem[1], leftTime = data.leftTime;
rePaintTimeDom(node, leftTime);
data.timeToStart = 0;
self._changeStatus({isStart:true,node:node})
}
if(ev.isOver){
oItem = itemList[ev.nodeIndex], node = oItem[0];
var leftTimeEl = DOM.get('span.J_TimeLeft', node),end = ev.end;
DOM.html(leftTimeEl, S.substitute(template, self._timeFormat(end)));
self._changeStatus({isOver:true,node:node});
remove(node);
}
})
}
}
},
/*_itemList : function(){
var self = this;
var list = self._getList();
self._itemEls = list['itemsEls'];
self._itemIds = list['itemIds'];
return list;
},*/
_init : function() {
var self = this, container = self.container;
self.start = +new Date();
// self._itemList();
self._getList();
self._getData();
},
/*
* 获取商品节点
* */
_getList: function() {
var self = this;
var itemsEL = DOM.query('.paimai-item');
var items = [],
ids = [];
for (var i = 0,len = itemsEL.length; i < len; i++) {
items[itemsEL[i].getAttribute('data-itemid')] = itemsEL[i];
ids.push(itemsEL[i].getAttribute('data-itemid'));
}
self._itemEls = items;
self._itemIds = ids;
return {
itemsEls: items,
itemIds: ids
};
},
/*
* 请求接口获取数据
* */
_getData : function() {
var self = this, itemEls = self._itemEls, itemIds = self._itemIds;
if (itemIds.length == 0) {
var timer = self.timer();
timer.onStop();
timer.run();
new Switch('#J_TabContainer');
self._getMpp();
return;
}
var ids = itemIds.splice(0,20);
self._itemIds = itemIds;
S.getScript(api + 'itemIds=' + ids.join(',') + '&t=' + new Date().getTime(), function() {
if (!getLegacyAuction) {
return;
}
var _g = getLegacyAuction.list;
getLegacyAuction = null;
for (var i = 0,len = _g.length; i < len; i++) {
self._paint(itemEls[_g[i].itemId], _g[i]);
}
self._getData();
})
},
_paint: function(node, data) {
var itemId = data.itemId,leftTime = data.leftTime, end = data.end, timeToStart = data.timeToStart, currentPrice = data.currentPrice,
bidCnt = data.bidCnt,quantity = data.quantity, buttonEl = DOM.get('.pai-button',node),
self = this, timeFormat = self._timeFormat, timer = this.timer();
template = '{h}点{m}分{s}秒';
var bigPriceEL = DOM.get('.big-price',node), decimalEl = DOM.get('.decimal',node), priceTitleEl = DOM.get('.label',node),
auctionCnt = DOM.get('.J_AuctionCount',node), storageEl = DOM.get('.storage',node), timeTitleEl = DOM.get('.J_TimeTitle',node),
priceArr = currentPrice.split('.');
DOM.html(bigPriceEL, priceArr[0]+'.');
DOM.html(decimalEl, priceArr[1]);
DOM.html(auctionCnt, bidCnt);
DOM.html(storageEl, quantity);
if(timeToStart > 0){
DOM.html(timeTitleEl, '距离开拍');
DOM.addClass(buttonEl,'will-begin');
}
if (leftTime < 0) {
var leftTimeEl = DOM.get('span.J_TimeLeft', node);
self._changeStatus({isOver:true,node:node});
DOM.addClass(buttonEl, 'time-out');
if (bidCnt > 0) {
DOM.html(priceTitleEl, '成交价格');
}
DOM.html(leftTimeEl, S.substitute(template, timeFormat(end)));
timer.addOver(node);
return;
}
timer.add([node,data]);
},
_changeStatus:function(status){
var EL_PRICE_TITLE = '.J_PriceTitle', EL_TIME_TITLE ='.J_TimeTitle', EL_BUTTON = '.pai-button',EL_CNT = '.J_AuctionCount',
TXT_DEAL_PRICE = '成交价格',TXT_DEAL_TIME = '成交时间', TXT_OVER_TIME='结束时间',TXT_LEFT_TIME='剩余时间';
var node = status.node, priceTitleEl = DOM.get(EL_PRICE_TITLE,node),timeTitleEl = DOM.get(EL_TIME_TITLE,node),
buttonConEl = DOM.get(EL_BUTTON,node),bidCntEl = DOM.get(EL_CNT,node);
if (status.isStart) {
DOM.html(timeTitleEl, TXT_LEFT_TIME);
DOM.removeClass(buttonConEl, 'will-begin');
}
if(status.isOver){
if(DOM.html(bidCntEl) > 0){
DOM.html(timeTitleEl, TXT_DEAL_TIME);
DOM.html(priceTitleEl,TXT_DEAL_PRICE);
}
else{
DOM.html(timeTitleEl, TXT_OVER_TIME);
}
DOM.removeClass(buttonConEl,'will-begin');
DOM.addClass(buttonConEl,'time-out');
}
},
/*
* 将时间段微秒转化为天,时,分,秒的形式
* */
_timeSplit: function(ms) {
var self = this, addZero = self._addZero, s = Math.floor(ms / 1000);
if (s < 0) {
return false;
}
var sec = s % 60,
min = Math.floor(s / 60) % 60,
hour = Math.floor(s / 3600) % 24,
day = parseInt((s / 3600) / 24, 10);
return {
d: day,
s: addZero(sec),
m: addZero(min),
h: addZero(hour + 24 * day)
};
},
/*
* 从时间点微秒提取'HH:MM:ss"
* */
_timeFormat: function(ms) {
var self = this, addZero = self._addZero,
newDate = new Date(Number(ms));
//将时间点微秒转化为"yyyy-mm-dd' 'HH:MM:ss"的形式,
var re = newDate.toTimeString().slice(0, 8).split(':');
return {
h: re[0],
m: re[1],
s: re[2]
}
},
_addZero: function(n) {
if (n < 10) {
n = '0' + n;
}
return n;
},
//建立长链接
_getMpp: function() {
var self = this, itemEls = self._itemEls, itemIds = self._itemIds;
function updateSAU(oJson) {
update(itemEls[oJson.itemId], oJson);
}
function update(node, data) {
var auctionCnt = DOM.get('em.J_AuctionCount', node),bigPriceEL = DOM.get('.big-price', node), decimalEl = DOM.get('.decimal', node),
currentPrice = data.price,bidCnt = data.totalCnt;
var priceArr = currentPrice.split('.');
DOM.html(bigPriceEL, priceArr[0] + '.');
DOM.html(decimalEl, priceArr[1]);
DOM.html(auctionCnt, bidCnt);
}
var longlivedURL = 'http://a.tbcdn.cn/p/tstart/1.0/build/tb-mpp-min.js?t=20110920.js';
S.getScript(longlivedURL, function() {
if (!g_config) return;
Mpp.Notify.register({appId:g_config.appId, type:1, callback:updateSAU});
})
}
});
return Countdown;
}, {requires:['dom','Switch']});
/**
* @fileoverview 限时拍swtich切换脚本
* @author 易敛<yilian.wj@taobao.com>
* @date 12-1-8
*/
KISSY.add('Switch', function (S, DOM, Event, Tabs) {
var oTabs;
function Switch(container, config) {
var cfg = {
markupType:0,
effect:'none',
steps:1,
triggerType:'click'
};
this.container = container;
this.config = S.merge(cfg, config);
this._init();
}
S.augment(Switch, {
/*
* 初始化switchable
* */
_init:function () {
var self = this, cfg = self.config, container = self.container;
if (!S.get(container)) {
return;
}
self.curIndex = 0;
oTabs = new Tabs(container, cfg);
self._switchCtrl();
self._timeEnd();
},
/**
* 到点后自动跳转到下一个选项卡
*/
_timeEnd : function(){
if(!S.isObject(oTabs)) return false;
var self = this;
_switchToNext();
function _switchToNext(){
setInterval(function(){
var isTimeEnd = self._getArea(),
curIndex = self.curIndex;
if(isTimeEnd === curIndex + 2){
self._switchCtrl();
}
},2000);
}
},
_switchCtrl:function () {
var self = this;
function isOver(index) {
var panel = oTabs.panels[index - 1], overItems = S.all('.time-out',panel);
itemEl = S.all('.paimai-item',panel);
if (overItems) {
if(overItems.length == itemEl.length){
return true;
}
}
return false;
}
function getIndex(index) {
if (index < 4 && isOver(index)) {
index += 1;
}
return index;
}
function _index () {
var index;
switch (self._getArea()) {
case 1 :
index = getIndex(1);
break;
case 2 :
index = getIndex(2);
break;
case 3 :
index = getIndex(3);
break;
case 4 :
index = getIndex(4);
break;
default:
index = 0;
}
index --;
return index;
}
//设置g_config,为建立长链接做准备
function setMpp(index) {
var panel = oTabs.panels[index], itemsEl = S.all('.paimai-item', panel),itemIds = [];
for (var i = 0; i < itemsEl.length; i++) {
var itemId = DOM.attr(itemsEl[i],'data-itemid');
itemId && itemIds.push(itemId);
}
window.g_config = {appId:1009,itemId: itemIds};
}
self.curIndex = _index();
oTabs.switchTo(self.curIndex);
setMpp(self.curIndex);
var _indexs = self._getIndex(); //在这里调用_changeTitle函数
self._changeTitle(_indexs);
},
//添加的函数→→→→→→→→→→→→→→→→→→→→→→→→→→→修改标题
_changeTitle:function(timeIndex){
var cont = KISSY.all(this.container),
getLis = cont.children(".ks-switchable-nav").children('li'),
len = getLis.length;
KISSY.each(getLis,function(value,key){
if(key < len - 1){ //最后一个不用考虑
var span = KISSY.all(value).one('span.sub-title');
if(key < timeIndex -1){
span.html('(已经结束)');
}else if(key === timeIndex -1){
span.html('(正在进行)');
}else{
span.html('(即将开始)');
}
}
});
},
//添加的函数→→→→→→→→→→→→→→→→→→→→→→→→→→→通过当前时间获取索引
_getIndex:function(){
var date = new Date(),
hour = date.getHours(),
index,time;
if(hour < 10){
index = 0;
}else if(hour >= 22){
index = 5;
}else{
index = parseInt((hour - 10)/3,10) + 1; //1,2,3,4
}
return index;
},
_formatTime:function (hour) {
var devide = new Date();
devide.setHours(hour);
devide.setMinutes(0);
devide.setSeconds(0);
return devide;
},
_getArea:function () {
var self = this,now = +new Date();
var firstStart = +self._formatTime(10),
firstEnd = +self._formatTime(13),
secondStart = +self._formatTime(13),
secondEnd = +self._formatTime(16),
thirdStart = +self._formatTime(16),
thirdEnd = +self._formatTime(19),
fourthStart = +self._formatTime(19),
fourthEnd = +self._formatTime(22);
if ((now >= firstStart && now <= firstEnd) || now < firstStart) {
return 1;
}
else if ((now >= secondStart && now <= secondEnd) || (now > secondEnd && now < thirdStart)) {
return 2;
}
else if ((now >= thirdStart && now <= thirdEnd) || (now > thirdEnd && now < fourthStart)) {
return 3;
}
else if ((now >= fourthStart && now <= fourthEnd) || now > fourthEnd) {
return 4;
}
else {
return 0;
}
}
});
return Switch;
}, {requires:['dom', 'event', 'switchable']});
/**
* @fileoverview 天天拍脚本初始化
* @author 易敛<yilian.wj@taobao.com>
* @date 12-1-8
*/
KISSY.add('tiantian', function (S, DOM, Event, Switch, Countdown) {
function TianTian() {
new Countdown();
// new Switch('#J_TabContainer');
}
return TianTian;
}, {requires:['dom', 'event', 'Switch', 'Countdown']});
@czy88840616
Copy link
Author

1、入口可以单例
2、26、31、44行风格不一致,统一一种定义函数的风格
3、 私有变量下划线一会加一会没加。。31和44行
4、125行_init 最好能放在第一个,比较直观,一看就是入口

@czy88840616
Copy link
Author

整体3个模块的话可以分成3个文件保存,公共模块可以重用的话,或者预备重用可以单独弄成模块,比如Countdown可以抽出去做为应用公共组件,同时Countdown可以再分出一些小的业务模块,_paint里的模版也可以抽出来,作为参数类传入Countdown,作为可配置的方式存在

@czy88840616
Copy link
Author

KISSY好多啊。。都改成S吧。。
setInterval都可以换成S.later吧

@czy88840616
Copy link
Author

154行的_getData这个函数,Countdown依赖了Switch有点怪,如果Countdown作为组件存在,Switch更像是一个回调的函数,这样想_getData可以暴露一个callback,在其他地方去new Switch

至于CountDown的timer,更像是类中的子类,可以拿到顶层中,不然每次创建CountDown的实例都会调用timer()方法来执行多次其中的函数,而_getData又会创建多个timer(),目的就是为了创建多个timer的实例

@shenmao1989
Copy link

只恩呢刚评论

update by harry

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment