avalon2
Version:
an elegant efficient express mvvm framework
312 lines (305 loc) • 13 kB
JavaScript
function Calender() {
this.initialize.apply(this, arguments);
}
Calender.helpers = {
// 选择元素
$$: function(arg, context) {
var tagAll, n, eles = [],
i, sub = arg.substring(1);
context = context || document;
if (typeof arg == 'string') {
switch (arg.charAt(0)) {
case '#':
return document.getElementById(sub);
case '.':
if (context.getElementsByClassName) return context.getElementsByClassName(sub);
tagAll = Calender.helpers.$$('*', context);
n = tagAll.length;
for (i = 0; i < n; i++) {
if (tagAll[i].className.indexOf(sub) > -1) eles.push(tagAll[i]);
}
return eles;
default:
return context.getElementsByTagName(arg);
}
}
},
// 绑定事件
bind: function(node, type, handler) {
node.addEventListener ? node.addEventListener(type, handler, false) : node.attachEvent('on' + type, handler);
},
// 获取元素位置
getPos: function(node) {
var scrollx = document.documentElement.scrollLeft || document.body.scrollLeft,
scrollt = document.documentElement.scrollTop || document.body.scrollTop;
pos = node.getBoundingClientRect();
return { top: pos.top + scrollt, right: pos.right + scrollx, bottom: pos.bottom + scrollt, left: pos.left + scrollx }
},
// 添加样式名
addClass: function(c, node) {
node.className = node.className + ' ' + c;
},
// 移除样式名
removeClass: function(c, node) {
var reg = new RegExp("(^|\\s+)" + c + "(\\s+|$)", "g");
node.className = node.className.replace(reg, '');
},
//判断是否有类名
hasClass: function(c, node) {
c = c || '';
if (c.replace(/\s/g, '').length == 0) return false;
return new RegExp(' ' + c + ' ').test(' ' + node.className + ' ');
},
// 阻止冒泡
stopPropagation: function(event) {
event = event || window.event;
event.stopPropagation ? event.stopPropagation() : event.cancelBubble = true;
}
};
Calender.prototype = {
constructor: Calender,
// 模板数组
_template: [
'<dl>',
'<dt class="title-date">',
'<span class="prevyear">prevyear</span><span class="prevmonth">prevmonth</span>',
'<span class="nextyear">nextyear</span><span class="nextmonth">nextmonth</span>',
'</dt>',
'<dt><strong>日</strong></dt>',
'<dt>一</dt>',
'<dt>二</dt>',
'<dt>三</dt>',
'<dt>四</dt>',
'<dt>五</dt>',
'<dt><strong>六</strong></dt>',
'<dd></dd>',
'</dl>'
],
// 初始化对象
initialize: function(options) {
this.id = options.id; // input的ID
this.end = options.end;
this.begin = options.begin;
this.input = Calender.helpers.$$('#' + this.id); // 获取INPUT元素
this.inputEvent(); // input的事件绑定,获取焦点事件
},
// 创建日期最外层盒子,并设置盒子的绝对定位
createContainer: function() {
// 如果存在,则移除整个日期层Container
var odiv = Calender.helpers.$$('#' + this.id + '-date');
if (!!odiv) odiv.parentNode.removeChild(odiv);
var container = this.container = document.createElement('div');
container.id = this.id + '-date';
container.style.position = "absolute";
container.zIndex = 999;
// 获取input表单位置inputPos
var input = Calender.helpers.$$('#' + this.id),
inputPos = Calender.helpers.getPos(input);
// 根据input的位置设置container高度
container.style.left = inputPos.left + 'px';
container.style.top = inputPos.bottom - 1 + 'px';
// 设置日期层上的单击事件,仅供阻止冒泡,用途在日期层外单击关闭日期层
Calender.helpers.bind(container, 'click', Calender.helpers.stopPropagation);
document.body.appendChild(container);
},
// 渲染日期
drawDate: function(odate) { // 参数 odate 为日期对象格式
var dateWarp, titleDate, dd, year, month, date, days, weekStart, i, l, ddHtml = [],
textNode;
var beginyear, beginmonth, begindate, endyear, endmonth, enddate;
this.dateWarp = dateWarp = document.createElement('div');
dateWarp.className = 'calendar';
dateWarp.innerHTML = this._template.join('');
this.year = year = odate.getFullYear();
this.month = month = odate.getMonth() + 1;
this.date = date = odate.getDate();
beginyear = this.begin.getFullYear();
beginmonth = this.begin.getMonth() + 1;
begindate = this.begin.getDate();
endyear = this.end.getFullYear();
endmonth = this.end.getMonth() + 1;
enddate = this.end.getDate();
this.titleDate = titleDate = Calender.helpers.$$('.title-date', dateWarp)[0];
textNode = document.createTextNode(year + '年' + month + '月');
titleDate.appendChild(textNode);
this.btnEvent();
// 获取模板中唯一的DD元素
this.dd = dd = Calender.helpers.$$('dd', dateWarp)[0];
// 获取本月天数
days = new Date(year, month, 0).getDate();
// 获取本月第一天是星期几
weekStart = new Date(year, month - 1, 1).getDay();
// 开头显示空白段
for (i = 0; i < weekStart; i++) {
ddHtml.push('<a> </a>');
}
// 循环显示日期
for (i = 1; i <= days; i++) {
if (year < beginyear) {
ddHtml.push('<a class="live disabled">' + i + '</a>');
} else if (year == beginyear) {
if (month < beginmonth) {
ddHtml.push('<a class="live disabled">' + i + '</a>');
} else if (month == beginmonth) {
if (i < begindate) ddHtml.push('<a class="live disabled">' + i + '</a>');
if (i == begindate) ddHtml.push('<a class="live">' + i + '</a>');
if (i > begindate) {
if (endyear == year && endmonth == month) {
if (enddate < i) {
ddHtml.push('<a class="live disabled">' + i + '</a>');
} else {
ddHtml.push('<a class="live">' + i + '</a>')
}
} else {
ddHtml.push('<a class="live">' + i + '</a>')
}
}
} else if (month > beginmonth) {
if (endyear < year) {
ddHtml.push('<a class="live disabled">' + i + '</a>');
} else if (endyear == year) {
if (endmonth < month) {
ddHtml.push('<a class="live disabled">' + i + '</a>');
} else if (endmonth == month) {
if (i < enddate) ddHtml.push('<a class="live">' + i + '</a>');
if (i == enddate) ddHtml.push('<a class="live">' + i + '</a>');
if (i > enddate) ddHtml.push('<a class="live disabled">' + i + '</a>')
} else {
ddHtml.push('<a class="live">' + i + '</a>');
}
} else if (endyear > year) {
ddHtml.push('<a class="live">' + i + '</a>');
}
}
} else if (year > beginyear) {
if (endyear < year) {
ddHtml.push('<a class="live disabled">' + i + '</a>');
} else if (endyear == year) {
if (endmonth < month) {
ddHtml.push('<a class="live disabled">' + i + '</a>');
} else if (endmonth == month) {
if (i < enddate) ddHtml.push('<a class="live">' + i + '</a>');
if (i == enddate) ddHtml.push('<a class="live">' + i + '</a>');
if (i > enddate) ddHtml.push('<a class="live disabled">' + i + '</a>')
} else {
ddHtml.push('<a class="live">' + i + '</a>');
}
}
}
}
dd.innerHTML = ddHtml.join('');
// 如果存在,则先移除
this.removeDate();
// 添加
this.container.appendChild(dateWarp);
//IE6 select遮罩
var ie6 = !!window.ActiveXObject && !window.XMLHttpRequest;
if (ie6) dateWarp.appendChild(this.createIframe());
this.valueChoose(year, month);
// A link事件绑定
this.linkOn();
// 区域外事件绑定
this.outClick();
},
createIframe: function() {
var myIframe = document.createElement('iframe');
myIframe.src = 'about:blank';
myIframe.style.position = 'absolute';
myIframe.style.zIndex = '-1';
myIframe.style.left = '-1px';
myIframe.style.top = 0;
myIframe.style.border = 0;
myIframe.style.opacity = 0;
myIframe.style.filter = 'alpha(opacity= 0 )';
myIframe.style.width = this.container.offsetWidth + 'px';
myIframe.style.height = this.container.offsetHeight + 'px';
return myIframe;
},
//回填选中状态
valueChoose: function(y, m) {
var val = this.input.value;
var arr = val.split('-');
if (val) {
if ((arr[0] == y) && (arr[1] == m)) {
var links = Calender.helpers.$$('.live', this.dd);
var i = Number(arr[2]);
Calender.helpers.addClass("this", links[i - 1]);
}
}
},
// 移除日期DIV.calendar
removeDate: function() {
var odiv = Calender.helpers.$$('.calendar', this.container)[0];
if (!!odiv) this.container.removeChild(odiv);
},
// 上一月,下一月按钮事件
btnEvent: function() {
var prevyear = Calender.helpers.$$('.prevyear', this.dateWarp)[0],
prevmonth = Calender.helpers.$$('.prevmonth', this.dateWarp)[0],
nextyear = Calender.helpers.$$('.nextyear', this.dateWarp)[0],
nextmonth = Calender.helpers.$$('.nextmonth', this.dateWarp)[0],
that = this;
prevyear.onclick = function() {
var idate = new Date(that.year - 1, that.month - 1, that.date);
that.drawDate(idate);
};
prevmonth.onclick = function() {
var idate = new Date(that.year, that.month - 2, that.date);
that.drawDate(idate);
};
nextyear.onclick = function() {
var idate = new Date(that.year + 1, that.month - 1, that.date);
that.drawDate(idate);
};
nextmonth.onclick = function() {
var idate = new Date(that.year, that.month, that.date);
that.drawDate(idate);
}
},
// A 的事件
linkOn: function() {
var links = Calender.helpers.$$('.live', this.dd),
i, l = links.length,
that = this;
for (i = 0; i < l; i++) {
links[i].index = i;
links[i].onmouseover = function() {
if (Calender.helpers.hasClass("disabled", this)) {
return
}
Calender.helpers.addClass("on", links[this.index]);
};
links[i].onmouseout = function() {
Calender.helpers.removeClass("on", links[this.index]);
};
links[i].onclick = function() {
if (Calender.helpers.hasClass("disabled", this)) {
return
}
Calender.helpers.addClass("this", this);
that.date = this.innerHTML;
that.input.value = that.year + '-' + that.month + '-' + that.date;
that.removeDate();
}
}
},
// 表单的事件
inputEvent: function() {
var that = this;
Calender.helpers.bind(that.input, 'focus', function() {
that.createContainer();
that.drawDate(that.begin);
});
},
// 鼠标在对象区域外点击,移除日期层
outClick: function() {
var that = this;
Calender.helpers.bind(document, 'click', function(event) {
event = event || window.event;
var target = event.target || event.srcElement;
if (target == that.input) return;
that.removeDate();
})
}
};
var myDate1 = new Calender({ id: 'j_Date1', 'begin': new Date(), 'end': new Date('2017-10-09') });