/*
ZZSWidget.js 版本号2021.06.29
目前共有单选、多选、日历、文本框、文本域、按钮 6个控件
2021.06.29增加了单选、多选和日历控件的options的widgetParentNode属性,可以自由设置每一个的widgetParentNode了,这样就可在多个滚动条的地方不响应其他滚动条的事件
2021.06.28 增加ZZSWidget.setWidgetParentNode()方法,现在可以设置非document.body作为单选多选日历控件的parentNode了,这样可以使一些跟随滚动条滚动的情况不会出现panel飞出特定的元素视窗,起到美观的作用
目前该方法可以传入id或直接传入dom对象。注意,该对象会被附上position:relative属性,如果有滚动条则会自动跟随滚动。请不要随意使用该方法。一般该方法用于绑定存在滚动条的那一个非body对象。
2021.06.28 解决单选多选不满最大高度时上置偏移的问题
2021.06.27 增加按钮控件
2021.06.27 为小三角增加双事件,点击第二次会自动关闭,增加控件对滚动条(高度)的自动判断功能。如果滚动条有变化,会自动跟踪其变化重新适应
2021.06.25 将滚动事件绑定到外部的每一层符合要求的元素上,而不是只绑定一个,并且设置控件自动判断滚动条高度和自动控制出现位置
2021.06.25 增加自动判断控件绑定的外部元素高度的功能,如果为空,则赋予默认值
2021.06.25 增加ZZSWidget.getValue(id,value)方法
2021.06.24 给所有控件统一增加onlytips和placeholder、offsetHeight属性
2021.06.24 增加Widget.getResult(id,t)方法
2021.06.23 增加文本框、文本域控件
2021.06.23 给文本框控件添加正则校验功能
2021.06.22 增加日历控件到达屏幕下方显示不全自动上置的功能
2021.06.21 增加日历控件
2021.06.19 增加多选控件
2021.06.18 开始制作,初步完成单选控件
增加各种控件随滚动条自由移动的功能
Option(单选)控件:
ZZSOption(id,[1,2,3],offsetHeight:20,placeholder:"123",onlytips:true});
offsetHeight是高度向下偏移量
placeholder是默认值
onlytips表示placeholder的内容是否是可用的实际值,还是只是一个提示语,默认true,只是一个提示语,当为false时则是一个默认值,用Widget.getResult()的时候是会返回该值的
MultipleOption(多选)控件:
ZZSMultipleOption(id,[1,2,3],{offsetHeight:20,placeholder:"123",onlytips:true});
offsetHeight是高度向下偏移量
placeholder是默认值
onlytips表示placeholder的内容是否是可用的实际值,还是只是一个提示语,默认true,只是一个提示语,当为false时则是一个默认值,用Widget.getResult()的时候是会返回该值的
Calendar(日历)控件:
ZZSCalendar(id,{offsetHeight:20,placeholder:"__today__"});
第一个参数是目标id
第二个参数是一个对象,目前支持offsetHeight和placeholder两个属性
offsetHeight是偏移y绝对值
placeholder是默认显示的数值,以灰色字体显示,当为“__today__”时显示今天的时间
INPUT(文本框)控件:
ZZSInput(id,{minusHeight:0,minusWidth:4,placeholder:"请输入数字",onlyinput:"number"})
minusHeight和minusWidth属性可以缩小input控件相对于外部标签的大小,如果外部标签高度为0,则自动变成高度20px。
placeholder属性不再赘述
onlytips如果为false则placeholder会变成默认文本值,默认为true
onlyinput属性表示设置只能输入某些值,当设为num或number时只能输入阿拉伯数字、加减号和小数点;
当设为chn或chinese时只能输入中文
当设为letter时只能输入英文
TEXTAREA(文本域)控件:
与INPUT控件完全一致,只是将input变成textarea
如果外部标签没有高度则默认高度为40px
Button(按钮)控件:
ZZSButton(id,function(){alert(1)},{text:"按钮上面的字",width:100,height:100,borderRadius:10})
这里的function是点击事件
width height borderRadius属性为可选项,不需要带上"px"或"pt"等单位字眼
Widget.getResult(id,t)方法:
该方法用于获取绑定控件的对象上面的值
如果placeholder设为onlytips则返回的值为空字符串
如果t为空则放回一个对象{value:"某个value",type:"某个type"}
如果t为value就直接返回value
如果t为type就直接返回type,type有五种,分别是Option MultipleOption Calendar Input Textarea
Widget.setValue(id,v)方法:
该方法用于对已经绑定控件的目标元素设置一个值,目标对象是否设置onlytips为true没有影响
*/
window.ZZSWidget = function(){}
ZZSWidget.widgetParentNode = document.body;
ZZSWidget.isDOM = (typeof HTMLElement === 'object') ? function(obj){return obj instanceof HTMLElement;} :
function(obj){return obj && typeof obj === 'object' && (obj.nodeType === 1 || obj.nodeType === 9) && typeof obj.nodeName === 'string';}
ZZSWidget.Inside = function(a,b){ //a元素是否是b元素的子对象或孙,孙孙孙……对象
while(a){
a = a.parentNode;
if(a == b) return true
}
return false
}
window.ZZSOption = function(targetid,data,options){
options = (Object.prototype.toString.call(options)==='[object Object]')?options:{};
var offsetHeight = 'offsetHeight' in options?options['offsetHeight']:0;
var onlytips = ('onlytips' in options&&options['onlytips']==false)?false:true;
var placeholder = 'placeholder' in options?options['placeholder']:'';
if('widgetParentNode' in options){
if(document.getElementById(options['widgetParentNode'])){
window.ZZSOption.widgetParentNodes[targetid] = document.getElementById(options['widgetParentNode']);
}else if(ZZSWidget.isDOM(options['widgetParentNode'])){
window.ZZSOption.widgetParentNodes[targetid] = options['widgetParentNode'];
}
window.ZZSOption.widgetParentNodes[targetid].style.position = 'relative';
}
function decorate(arr){
var str = "["
for(var i=0;i<arr.length;i++){
str += (Number.isFinite(arr[i])?arr[i]:"'"+arr[i]+"'") +","
}
return str.slice(0,-1)+"]";
}
var tar = document.getElementById(targetid);
if(!tar){
throw Error("ZZSOption控件无法绑定到id为【"+targetid+"】的元素上");
}
tar.innerHTML = '<div style="width:100%;height:100%;margin:0;padding:0;"><span class="ZZSWidgetOutput" ZZSWidgetType="Option" onlytips=\''+onlytips+'\' placeholder=\''+placeholder+'\' style="display:inline-block;height:100%;width:'+ (tar.clientWidth-18) +'px;">'+(placeholder?(onlytips?'<span style="color:gray;">'+placeholder+'</span>':placeholder):'')+'</span>\
<span onmouseout="this.style.color=\'deepskyblue\'" onmouseover="this.style.color=\'dodgerblue\'" style="cursor:pointer;float:right;color:deepskyblue;font-family:微软雅黑;background-color:#f1f1f1;display:inline-block;" onclick="ZZSOption.panel(this.parentNode,'+decorate(data)+',\''+targetid+'\','+offsetHeight+')" class="ZZSWidgetUnit">▼</span></div>';
}
ZZSOption.widgetParentNodes = {};
ZZSOption.scroller = [];
ZZSOption.panel = function(node,options,targetid,offsetHeight){
window.ZZSOption.currentTargetId = targetid;
var myWidgetParentNode = (targetid in window.ZZSOption.widgetParentNodes)?window.ZZSOption.widgetParentNodes[targetid]:window.ZZSWidget.widgetParentNode;
window.ZZSOption.myWidgetParentNode = myWidgetParentNode;
if(!window.ZZSOption.lastnode){
window.ZZSOption.lastnode = node;
}
if(window.ZZSOption.lastnode == node && document.getElementById("ZZSWidget") && document.getElementById("ZZSWidget").getAttribute("ZZSWidgetType")=="Option"){
document.getElementById("ZZSWidget").remove();
return
}
window.ZZSOption.lastnode = node;
var targetHeight = node.parentNode.offsetHeight?node.parentNode.offsetHeight:20;
function getAbsolutePosition(node) {
var position = { left:0, top:0 };
while(node){
position.left += node.offsetLeft;
position.top += node.offsetTop;
node = node.offsetParent;
}
return position;
}
var position = getAbsolutePosition(node.parentNode);
var x = position.left-1;
var y = position.top + targetHeight;
var w = node.offsetWidth+2;
if(myWidgetParentNode!=document.body){
y -= getAbsolutePosition(myWidgetParentNode).top;
}
y += offsetHeight;
var megaHeight = window.innerHeight;
window.ZZSOption.scroller = []; //2021.06.29升级,每次都把整个scroller重置,这样可以避免存在多个scroll域时只对一个域绑定scroll事件的情况
while(node){
node =node.parentNode;
if(node && (node.scrollHeight>node.clientHeight || node.offsetHeight>node.clientHeight)){
window.ZZSOption.scroller.push(node);
}
}
for(var i=0;i<window.ZZSOption.scroller.length;i++){
var sc = window.ZZSOption.scroller[i];
if(!sc.ZZSOptionBinded){ //此处会做判断,如果已经绑了就不会绑第二次了
sc.addEventListener("scroll",function(e){
if(document.getElementById("ZZSWidget")&&document.getElementById("ZZSWidget").getAttribute("ZZSWidgetType")=="Option"){
if(!ZZSWidget.Inside(document.getElementById(window.ZZSOption.currentTargetId),e.target)){ return }
if(window.ZZSOption.myWidgetParentNode!=document.body && (window.ZZSOption.myWidgetParentNode.style.overflowY=="auto"||window.ZZSOption.myWidgetParentNode.style.overflowY=="scroll")){return}
document.getElementById("ZZSWidget").style.top = (window.ZZSOption.y - (e.target.scrollTop - e.target.currentScrollTop)) + "px";
}
})
sc.ZZSOptionBinded = true
}
y -= sc.scrollTop;
if(sc.scrollHeight-sc.offsetHeight>0 && sc.scrollHeight!=0 && sc.offsetHeight!=0){
var tmpHeight = sc.scrollHeight + getAbsolutePosition(sc).top;
if(sc.style.overflowY && sc.style.overflowY=="hidden"){
tmpHeight = 0;
}
//var tmpHeight = window.innerHeight+sc.scrollHeight-sc.offsetHeight;
megaHeight = tmpHeight>megaHeight?tmpHeight:megaHeight;
}
}
var again = false
if(position.top + targetHeight + 122 > megaHeight){
again = true
y -= (122+offsetHeight*2+targetHeight);
}
if(myWidgetParentNode!=document.body && (myWidgetParentNode.style.overflowY=="auto"||myWidgetParentNode.style.overflowY=="scroll")){
y += myWidgetParentNode.scrollTop;
}
window.ZZSOption.x = x;
window.ZZSOption.y = y;
for(var i=0;i<window.ZZSOption.scroller.length;i++){
window.ZZSOption.scroller[i].currentScrollTop = window.ZZSOption.scroller[i].scrollTop;
}
if(document.getElementById("ZZSWidget")){
document.getElementById("ZZSWidget").remove();
}
var ZZSOptionPanel = '<div id="ZZSWidget" ZZSWidgetType="Option" class="ZZSWidgetUnit" style="overflow-y:auto;border:1px solid #777;width:'+w+'px;max-height:120px;background-color:#eee;position:absolute;left:'+x+'px;top:'+y+'px;">';
for(var i=0;i<options.length;i++){
ZZSOptionPanel += '<div onclick="ZZSOption.choose(\''+targetid+'\',this)" class="ZZSWidgetUnit" onmouseout="this.style.backgroundColor=\'#eee\'" onmouseover="this.style.backgroundColor=\'dodgerblue\'" style="border:1px solid white;cursor:pointer;" >'+options[i]+'</div>';
}
ZZSOptionPanel += '<div onclick="ZZSOption.choose(\''+targetid+'\',this,1)" class="ZZSWidgetUnit" onmouseout="this.style.backgroundColor=\'#eee\'" onmouseover="this.style.backgroundColor=\'dodgerblue\'" style="border:1px solid white;cursor:pointer;color:gray;">不选</div>'
ZZSOptionPanel += '</div>';
myWidgetParentNode.insertAdjacentHTML("beforeend",ZZSOptionPanel);
var rh = document.getElementById("ZZSWidget").offsetHeight;
if(again && rh<122){
y += 122 - rh;
if(position.top + targetHeight + rh < megaHeight){
y += rh + targetHeight;
}
window.ZZSOption.y = y;
document.getElementById("ZZSWidget").style.top = y + "px";
}
}
ZZSOption.choose = function(targetid,t,special){
document.getElementById('ZZSWidget').remove();
var o = document.getElementById(targetid).getElementsByClassName('ZZSWidgetOutput')[0];
if(special){
if(o.getAttribute('onlytips')=='true'){
console.log(o.getAttribute('placeholder'));
o.innerHTML = "<span style='color:gray;'>" + o.getAttribute('placeholder') + "</span>";
}else{
o.innerHTML = ""
}
}else{
o.innerHTML=t.innerHTML;
}
}
window.ZZSMultipleOption = function(targetid,data,options){
options = (Object.prototype.toString.call(options)==='[object Object]')?options:{};
var offsetHeight = 'offsetHeight' in options?options['offsetHeight']:0;
var onlytips = ('onlytips' in options&&options['onlytips']==false)?false:true;
var placeholder = 'placeholder' in options?options['placeholder']:'';
if('widgetParentNode' in options){
if(document.getElementById(options['widgetParentNode'])){
window.ZZSMultipleOption.widgetParentNodes[targetid] = document.getElementById(options['widgetParentNode']);
}else if(ZZSWidget.isDOM(options['widgetParentNode'])){
window.ZZSMultipleOption.widgetParentNodes[targetid] = options['widgetParentNode'];
}
window.ZZSMultipleOption.widgetParentNodes[targetid].style.position = 'relative';
}
function decorate(arr){
var str = "["
for(var i=0;i<arr.length;i++){
str += (Number.isFinite(arr[i])?arr[i]:"'"+arr[i]+"'") +","
}
return str.slice(0,-1)+"]";
}
var tar = document.getElementById(targetid);
if(!tar){
throw Error("ZZSMultipleOption控件无法绑定到id为【"+targetid+"】的元素上");
}
tar.innerHTML = '<div style="width:100%;height:100%;margin:0;padding:0;"><span class="ZZSWidgetOutput" ZZSWidgetType="MultipleOption" onlytips=\'' + onlytips + '\' placeholder=\'' + placeholder + '\' style="display:inline-block;height:100%;width:'+ (tar.clientWidth-18) +'px;">'+(placeholder?(onlytips?'<span style="color:gray;">'+placeholder+'</span>':placeholder):'')+'</span>\
<span onmouseout="this.style.color=\'deepskyblue\'" onmouseover="this.style.color=\'dodgerblue\'" style="cursor:pointer;float:right;color:deepskyblue;font-family:微软雅黑;background-color:#f1f1f1;display:inline-block;" onclick="ZZSMultipleOption.panel(this.parentNode,'+decorate(data)+',\''+targetid+'\','+offsetHeight+');" class="ZZSWidgetUnit">▼</span></div>';
}
ZZSMultipleOption.widgetParentNodes = {};
ZZSMultipleOption.scroller = [];
ZZSMultipleOption.panel = function(node,options,targetid,offsetHeight){
window.ZZSMultipleOption.currentTargetId = targetid;
var myWidgetParentNode = (targetid in window.ZZSMultipleOption.widgetParentNodes)?window.ZZSMultipleOption.widgetParentNodes[targetid]:window.ZZSWidget.widgetParentNode;
window.ZZSMultipleOption.myWidgetParentNode = myWidgetParentNode;
if(!window.ZZSMultipleOption.lastnode){
window.ZZSMultipleOption.lastnode = node;
}
if(window.ZZSMultipleOption.lastnode == node && document.getElementById("ZZSWidget") && document.getElementById("ZZSWidget").getAttribute("ZZSWidgetType")=="MultipleOption"){
document.getElementById("ZZSWidget").remove();
return
}
window.ZZSMultipleOption.lastnode = node;
var targetHeight = node.parentNode.offsetHeight?node.parentNode.offsetHeight:20;
function getAbsolutePosition(node) {
var position = { left:0, top:0 };
while(node){
position.left += node.offsetLeft;
position.top += node.offsetTop;
node = node.offsetParent;
}
return position;
}
var position = getAbsolutePosition(node.parentNode);
var x = position.left-1;
var y = position.top + targetHeight;
var w = node.offsetWidth+2;
if(myWidgetParentNode!=document.body){
y -= getAbsolutePosition(myWidgetParentNode).top;
}
y += offsetHeight;
var megaHeight = window.innerHeight;
window.ZZSMultipleOption.scroller = [];
while(node){
node =node.parentNode;
if(node && (node.scrollHeight>node.clientHeight || node.offsetHeight>node.clientHeight)){
window.ZZSMultipleOption.scroller.push(node);
}
}
for(var i=0;i<window.ZZSMultipleOption.scroller.length;i++){
var sc = window.ZZSMultipleOption.scroller[i];
if(!sc.ZZSMultipleOptionBinded){
sc.addEventListener("scroll",function(e){
if(document.getElementById("ZZSWidget")&&document.getElementById("ZZSWidget").getAttribute("ZZSWidgetType")=="MultipleOption"){
if(!ZZSWidget.Inside(document.getElementById(window.ZZSMultipleOption.currentTargetId),e.target)){ return }
if(window.ZZSMultipleOption.myWidgetParentNode!=document.body && (window.ZZSMultipleOption.myWidgetParentNode.style.overflowY=="auto"||window.ZZSMultipleOption.myWidgetParentNode.style.overflowY=="scroll")){return}
document.getElementById("ZZSWidget").style.top = (window.ZZSMultipleOption.y - (e.target.scrollTop - e.target.currentScrollTop)) + "px";
}
})
sc.ZZSMultipleOptionBinded = true
}
y -= sc.scrollTop;
if(sc.scrollHeight-sc.offsetHeight>0 && sc.scrollHeight!=0 && sc.offsetHeight!=0){
var tmpHeight = sc.scrollHeight + getAbsolutePosition(sc).top;
if(sc.style.overflowY && sc.style.overflowY=="hidden"){
tmpHeight = 0;
}
//var tmpHeight = window.innerHeight+sc.scrollHeight-sc.offsetHeight;
megaHeight = tmpHeight>megaHeight?tmpHeight:megaHeight;
}
}
var again = false
if(position.top + targetHeight + 150 > megaHeight){
again = true
y -= (150+offsetHeight*2+targetHeight);
}
if(myWidgetParentNode!=document.body && (myWidgetParentNode.style.overflowY=="auto"||myWidgetParentNode.style.overflowY=="scroll")){
y += myWidgetParentNode.scrollTop;
}
window.ZZSMultipleOption.x = x;
window.ZZSMultipleOption.y = y;
for(var i=0;i<window.ZZSMultipleOption.scroller.length;i++){
window.ZZSMultipleOption.scroller[i].currentScrollTop = window.ZZSMultipleOption.scroller[i].scrollTop;
}
if(document.getElementById("ZZSWidget")){
document.getElementById("ZZSWidget").remove();
}
var ZZSMultipleOptionPanel = '<div id="ZZSWidget" ZZSWidgetType="MultipleOption" class="ZZSWidgetUnit" style="width:'+w+'px;position:absolute;left:'+x+'px;top:'+y+'px;"><div style="border:1px solid #777;max-height:120px;overflow-y:auto;background-color:#eee;">';
for(var i=0;i<options.length;i++){
ZZSMultipleOptionPanel += '<div onclick="this.childNodes[0].checked = true;" class="ZZSWidgetUnit" onmouseout="this.style.backgroundColor=\'#eee\'" onmouseover="this.style.backgroundColor=\'dodgerblue\'" style="border:1px solid white;cursor:pointer;" ><input type="checkbox" class="ZZSWidgetUnit"/><span class="ZZSWidgetUnit">'+options[i]+'</span></div>';
}
ZZSMultipleOptionPanel += '</div><div style="cursor:pointer;background-color:dodgerblue;color:white;font-weight:bold;font-size:15px;line-height:26px;text-align:center;height:26px;border:1px solid #777;" onclick="ZZSMultipleOption.choose(\''+targetid+'\',this)">确定</div></div>';
myWidgetParentNode.insertAdjacentHTML("beforeend",ZZSMultipleOptionPanel);
var rh = document.getElementById("ZZSWidget").offsetHeight;
if(again && rh<150){
y += 150 - rh;
if(position.top + targetHeight + rh < megaHeight){
y += rh + targetHeight;
}
window.ZZSMultipleOption.y = y;
document.getElementById("ZZSWidget").style.top = y + "px";
}
}
ZZSMultipleOption.choose = function(targetid,t){
var tars = t.parentNode.getElementsByTagName('input');
var str = '';
for(var i=0;i<tars.length;i++){
if(tars[i].checked){
str += tars[i].nextSibling.innerHTML + ','
};
}
str=str.slice(0,-1);
var o = document.getElementById(targetid).getElementsByClassName('ZZSWidgetOutput')[0]
if(o.getAttribute('onlytips')=='true' && str== ''){
o.innerHTML = '<span style="color:gray;">'+ o.getAttribute('placeholder') + '</span>';
}
else if(o.getAttribute('onlytips')!='true' && str==''){
o.innerHTML = '';
}
else{
o.innerHTML = str;
}
document.getElementById('ZZSWidget').remove();
}
window.ZZSCalendar = function(targetid,options){
options = (Object.prototype.toString.call(options)==='[object Object]')?options:{};
var offsetHeight = 'offsetHeight' in options?options['offsetHeight']:0;
var onlytips = ('onlytips' in options&&options['onlytips']==false)?false:true;
var placeholder = 'placeholder' in options?options['placeholder']:null;
if('widgetParentNode' in options){
if(document.getElementById(options['widgetParentNode'])){
window.ZZSCalendar.widgetParentNodes[targetid] = document.getElementById(options['widgetParentNode']);
}else if(ZZSWidget.isDOM(options['widgetParentNode'])){
window.ZZSCalendar.widgetParentNodes[targetid] = options['widgetParentNode'];
}
window.ZZSCalendar.widgetParentNodes[targetid].style.position = 'relative';
}
if(placeholder=="__today__"){
var D = new Date();
var y = D.getFullYear();
var m = D.getMonth()+1;
m = m<10?"0"+m:m;
var d = D.getDate();
d = d<10?"0"+d:d;
placeholder = y + "-" + m + "-" + d;
}
function decorate(arr){
var str = "["
for(var i=0;i<arr.length;i++){
str += (Number.isFinite(arr[i])?arr[i]:"'"+arr[i]+"'") +","
}
return str.slice(0,-1)+"]";
}
var tar = document.getElementById(targetid);
if(!tar){
throw Error("ZZSCalendar控件无法绑定到id为【"+targetid+"】的元素上");
}
tar.innerHTML = '<div style="width:100%;height:100%;margin:0;padding:0;"><span class="ZZSWidgetOutput" ZZSWidgetType="Calendar" onlytips='+onlytips+' placeholder='+placeholder+' style="display:inline-block;height:100%;width:'+ (tar.clientWidth-18) +'px;">'+(placeholder?(onlytips?'<span style="color:gray;">'+placeholder+'</span>':placeholder):'')+'</span>\
<span onmouseout="this.style.color=\'deepskyblue\'" onmouseover="this.style.color=\'dodgerblue\'" style="cursor:pointer;float:right;color:deepskyblue;font-family:微软雅黑;background-color:#f1f1f1;display:inline-block;" onclick="ZZSCalendar.panel(this.parentNode,\''+targetid+'\','+offsetHeight+')" class="ZZSWidgetUnit">▼</span></div>';
}
ZZSCalendar.setYear = function(plus){
if(document.getElementById("ZZSCalendar_year")){
var year = parseInt(document.getElementById("ZZSCalendar_year").innerHTML);
year += plus;
document.getElementById("ZZSCalendar_year").innerHTML = year;
ZZSCalendar.setDay();
}
}
ZZSCalendar.setMonth = function(plus){
if(document.getElementById("ZZSCalendar_month")){
var month = parseInt(document.getElementById("ZZSCalendar_month").innerHTML);
month += plus;
if(month>12){
month = 1;
ZZSCalendar.setYear(1);
}
else if(month<1){
month = 12;
ZZSCalendar.setYear(-1);
}
document.getElementById("ZZSCalendar_month").innerHTML = month;
ZZSCalendar.setDay();
}
}
ZZSCalendar.setDay = function(){
var y = parseInt(document.getElementById("ZZSCalendar_year").innerHTML);
var m = parseInt(document.getElementById("ZZSCalendar_month").innerHTML);
ZZSCalendar_days = document.getElementsByClassName("ZZSCalendar_day");
for(var i=0;i<ZZSCalendar_days.length;i++){
ZZSCalendar_days[i].innerHTML = '';
ZZSCalendar_days[i].style.backgroundColor = '';
}
var D = new Date();
D.setFullYear(y,m-1,1);
var row = D.getDay();//从星期几开始,0是日,1是一,以此类推6是六
var column = 0;
var dates = 30; //天数
if(m==1 || m==3 || m==5 || m==7 || m==8 || m==10 || m==12){
dates = 31;
}
else if(m==4 || m==6 || m==9 || m==11){
dates = 30;
}
else if(m==2){
if((y%100!=0&&y%4==0)||y%400==0){ //闰年
dates = 29;
}
else{
dates = 28;
}
}
for(var i=1;i<dates+1;i++){
document.getElementById("ZZSCalendar_day_x"+row+"_y"+column).innerHTML = i;
if(y == new Date().getFullYear() && m == new Date().getMonth()+1 && i == new Date().getDate()){
document.getElementById("ZZSCalendar_day_x"+row+"_y"+column).style.backgroundColor = "gold";
}
row += 1;
if(row>6){
row = 0;
column += 1;
}
}
}
ZZSCalendar.widgetParentNodes = {};
ZZSCalendar.scroller = [];
ZZSCalendar.panel = function(node,targetid,offsetHeight){
window.ZZSCalendar.currentTargetId = targetid;
var myWidgetParentNode = (targetid in window.ZZSCalendar.widgetParentNodes)?window.ZZSCalendar.widgetParentNodes[targetid]:window.ZZSWidget.widgetParentNode;
window.ZZSCalendar.myWidgetParentNode = myWidgetParentNode;
if(!window.ZZSCalendar.lastnode){
window.ZZSCalendar.lastnode = node;
}
if(window.ZZSCalendar.lastnode == node && document.getElementById("ZZSWidget") && document.getElementById("ZZSWidget").getAttribute("ZZSWidgetType")=="Calendar"){
document.getElementById("ZZSWidget").remove();
return
}
window.ZZSCalendar.lastnode = node;
var targetHeight = node.parentNode.offsetHeight?node.parentNode.offsetHeight:20;
function getAbsolutePosition(node) {
var position = { left:0, top:0 };
while(node){
position.left += node.offsetLeft;
position.top += node.offsetTop;
node = node.offsetParent;
}
return position;
}
var position = getAbsolutePosition(node.parentNode);
var x = position.left-1;
var y = position.top + targetHeight;
var w = node.offsetWidth+2;
if(myWidgetParentNode!=document.body){
y -= getAbsolutePosition(myWidgetParentNode).top;
}
y += offsetHeight;
var megaHeight = window.innerHeight;
window.ZZSCalendar.scroller = [];
while(node){
node =node.parentNode;
if(node && (node.scrollHeight>node.clientHeight || node.offsetHeight>node.clientHeight)){
window.ZZSCalendar.scroller.push(node);
}
}
if(window.ZZSCalendar.scroller.length){
for(var i=0;i<window.ZZSCalendar.scroller.length;i++){
var sc = window.ZZSCalendar.scroller[i];
if(!sc.ZZSCalendarBinded){
sc.addEventListener("scroll",function(e){
if(document.getElementById("ZZSWidget")&&document.getElementById("ZZSWidget").getAttribute("ZZSWidgetType")=="Calendar"){
if(!ZZSWidget.Inside(document.getElementById(window.ZZSCalendar.currentTargetId),e.target)){ return }
if(window.ZZSCalendar.myWidgetParentNode!=document.body && (window.ZZSCalendar.myWidgetParentNode.style.overflowY=="auto"||window.ZZSCalendar.myWidgetParentNode.style.overflowY=="scroll")){return}
document.getElementById("ZZSWidget").style.top = (window.ZZSCalendar.y - (e.target.scrollTop - e.target.currentScrollTop)) + "px";
}
})
sc.ZZSCalendarBinded = true
}
y -= sc.scrollTop;
if(sc.scrollHeight-sc.offsetHeight>0 && sc.scrollHeight!=0 && sc.offsetHeight!=0){
var tmpHeight = sc.scrollHeight + getAbsolutePosition(sc).top;
if(sc.style.overflowY && sc.style.overflowY=="hidden"){
tmpHeight = 0;
}
//var tmpHeight = window.innerHeight+sc.scrollHeight-sc.offsetHeight;
megaHeight = tmpHeight>megaHeight?tmpHeight:megaHeight;
}
}
}
if(position.top + targetHeight + 201 > megaHeight){
y -= (201+offsetHeight*2+targetHeight);
}
if(myWidgetParentNode!=document.body && (myWidgetParentNode.style.overflowY=="auto"||myWidgetParentNode.style.overflowY=="scroll")){
y += myWidgetParentNode.scrollTop;
}
window.ZZSCalendar.x = x;
window.ZZSCalendar.y = y;
for(var i=0;i<window.ZZSCalendar.scroller.length;i++){
window.ZZSCalendar.scroller[i].currentScrollTop = window.ZZSCalendar.scroller[i].scrollTop;
}
if(document.getElementById("ZZSWidget")){
document.getElementById("ZZSWidget").remove();
}
var ZZSCalendarPanel = '<div id="ZZSWidget" class="ZZSWidgetUnit" style="overflow-y:auto;border:1px solid #777;background-color:#eee;position:absolute;left:'+x+'px;top:'+y+'px;">\
<table style="table-collapse:collapse;width:100%;text-align:center;" class="ZZSWidgetUnit">\
<tr class="ZZSWidgetUnit">\
<td onclick="ZZSCalendar.setYear(-1)" style="cursor:pointer;width:28px;" class="ZZSWidgetUnit">←</td>\
<td onclick="ZZSCalendar.setMonth(-1)" style="cursor:pointer;width:28px;" class="ZZSWidgetUnit"><</td>\
<td colspan="3" style="width:84px;" class="ZZSWidgetUnit"><span class="ZZSWidgetUnit" id="ZZSCalendar_year" style="color:dodgerblue;"></span>年<span id="ZZSCalendar_month" style="color:dodgerblue;" class="ZZSWidgetUnit"></span>月</td>\
<td onclick="ZZSCalendar.setMonth(1)" style="cursor:pointer;width:28px;" class="ZZSWidgetUnit">></td>\
<td onclick="ZZSCalendar.setYear(1)" style="cursor:pointer;width:28px;" class="ZZSWidgetUnit">→</td>\
</tr>\
<tr class="ZZSWidgetUnit">\
<td style="width:28px;" class="ZZSWidgetUnit">日</td>\
<td style="width:28px;" class="ZZSWidgetUnit">一</td>\
<td style="width:28px;" class="ZZSWidgetUnit">二</td>\
<td style="width:28px;" class="ZZSWidgetUnit">三</td>\
<td style="width:28px;" class="ZZSWidgetUnit">四</td>\
<td style="width:28px;" class="ZZSWidgetUnit">五</td>\
<td style="width:28px;" class="ZZSWidgetUnit">六</td>\
</tr>';
for(var i=0;i<6;i++){
ZZSCalendarPanel += '<tr>';
for(var j=0;j<7;j++){
ZZSCalendarPanel += '<td class="ZZSCalendar_day ZZSWidgetUnit" style="cursor:pointer;width:28px;height:20px;" onmouseout="this.style.backgroundColor=\'\';var d = new Date();if(this.innerHTML == d.getDate() && document.getElementById(\'ZZSCalendar_year\').innerHTML==d.getFullYear() && document.getElementById(\'ZZSCalendar_month\').innerHTML == d.getMonth()+1){this.style.backgroundColor=\'gold\'}" onmouseover="this.style.backgroundColor=\'dodgerblue\';" id="ZZSCalendar_day_x'+(j)+'_y'+(i)+'" onclick="ZZSCalendar.choose(this,\''+targetid+'\');"></td>';
}
ZZSCalendarPanel += '</tr>';
}
ZZSCalendarPanel += '</table></div>';
myWidgetParentNode.insertAdjacentHTML("beforeend",ZZSCalendarPanel);
document.getElementById("ZZSWidget").setAttribute("ZZSWidgetType","Calendar");
var d = new Date();
document.getElementById("ZZSCalendar_year").innerHTML = d.getFullYear();
document.getElementById("ZZSCalendar_month").innerHTML = d.getMonth()+1;
ZZSCalendar.setDay();
}
ZZSCalendar.choose = function(target,targetid){
var day = target.innerHTML;
var final = "";
if(day!=""){
day = parseInt(day)<10?("0"+day):day;
var month = document.getElementById("ZZSCalendar_month").innerHTML;
month = parseInt(month)<10?("0"+month):month;
var year = document.getElementById("ZZSCalendar_year").innerHTML;
final = year + "-" + month + "-" + day;
}
document.getElementById(targetid).getElementsByClassName("ZZSWidgetOutput")[0].innerHTML = final;
document.getElementById("ZZSWidget").remove();
}
window.ZZSInput = function(targetid,options){
options = (Object.prototype.toString.call(options)==='[object Object]')?options:{};
var tar = document.getElementById(targetid);
var placeholder = 'placeholder' in options?options['placeholder']:"";
var minusWidth = 'minusWidth' in options?options['minusWidth']:0;
var minusHeight = 'minusHeight' in options?options['minusHeight']:0;
var onlyinput = 'onlyinput' in options?options['onlyinput']:"";
var onlytips = ('onlytips' in options&&options['onlytips']==false)?false:true;
var type = ('type' in options && options['type']=="textarea")?options['type']:"input";
if(!tar){
throw Error((type=="input"?"ZZSInput":"ZZSTextarea")+"控件无法绑定到id为【"+targetid+"】的元素上");
}
var w = tar.clientWidth - minusWidth;
var h = (tar.clientHeight?tar.clientHeight:(type=="input"?20:40)) - minusHeight;
tar.innerHTML = '<'+type+' ZZSWidgetType="'+(type=="input"?"Input":"Textarea")+'" class="ZZSWidgetOutput" '+(onlytips?'placeholder':'value')+'="'+placeholder+'" type="text" style="width:'+ (w) + 'px;height:'+ (h) + 'px;border:1px solid dodgerblue;margin:auto;padding:0;display:block;"' + (type=="input"?'/>':'>'+(onlytips==false&&type=="textarea"?placeholder:'')+'</textarea>');
var op = tar.getElementsByClassName('ZZSWidgetOutput')[0];
var handle = function(e){}
switch(onlyinput){
case "number":
case "num":
case "数字":
handle = function(e){e.target.value = e.target.value.replace(/[^\n0-9\.\+\-]*/g,'');}
break
case "letter":
case "字母":
handle = function(e){e.target.value = e.target.value.replace(/[^\\\|\……\——\.\,\。\,\、\《\》\<\>\?\/\?\、\;\;\:\:\"\'\“\”\‘\’\[\]\{\}\【\】\-\+\_\=\*\/\(\)\(\)\!\!\~\·\@\#\$\%\^\&\n\sa-zA-Z]*/g,'');}
break
case "chinese": case "中文": case "Chinese": case "CHINESE": case "chn": case "Chn": case "CHN":
handle = function(e){
if(!ZZSInput.inputtingChinese){
e.target.value = e.target.value.replace(/[^\\\|\……\——\.\,\。\,\、\《\》\<\>\?\/\?\、\;\;\:\:\"\'\“\”\‘\’\[\]\{\}\【\】\-\+\_\=\*\/\(\)\(\)\!\!\~\·\@\#\$\%\^\&\n\s\u4e00-\u9fa5]*/g,'');
}
}
op.addEventListener("compositionstart",function(e){
ZZSInput.inputtingChinese = true
},false)
op.addEventListener("compositionend",function(e){
ZZSInput.inputtingChinese = false
e.target.value = e.target.value.replace(/[^\\\|\……\——\.\,\。\,\、\《\》\<\>\?\/\?\、\;\;\:\:\"\'\“\”\‘\’\[\]\{\}\【\】\-\+\_\=\*\/\(\)\(\)\!\!\~\·\@\#\$\%\^\&\n\s\u4e00-\u9fa5]*/g,'');
},false)
break
default:
break
}
op.addEventListener("change",function(e){handle(e)},false)
op.addEventListener("input",function(e){handle(e)},false)
}
ZZSInput.inputtingChinese = false;
window.ZZSTextarea = function(targetid,options){
options = (Object.prototype.toString.call(options)==='[object Object]')?options:{};
options["type"] = "textarea";
window.ZZSInput(targetid,options);
}
window.ZZSButton = function(targetid,func,options){
options = (Object.prototype.toString.call(options)==='[object Object]')?options:{};
var tar = document.getElementById(targetid);
if(!tar){
throw Error("ZZSButton控件无法绑定到id为【"+targetid+"】的元素上");
}
var width = 'width' in options?options['width']:0;
var height = 'height' in options?options['height']:0;
var borderRadius = 'borderRadius' in options?options['borderRadius']:0;
var text = 'text' in options?options['text']:'按钮';
if(!window.ZZSButton.funcs){
window.ZZSButton.funcs = {}
}
window.ZZSButton.funcs[targetid] = func
tar.innerHTML = '<div style="'+(borderRadius?"border-radius:"+borderRadius+"px;":"")+(width?"width:"+width+"px;":"")+(height?"height:"+height+"px;line-height:"+height+"px;":"")+'text-align:center;cursor:pointer;background-color:deepskyblue;margin:auto;" class="ZZSWidgetOutput" ZZSWidgetType="Button" onmouseout="this.style.backgroundColor=\'deepskyblue\'" onmouseover="this.style.backgroundColor=\'dodgerblue\';" onclick="window.ZZSButton.funcs[\''+targetid+'\']()">'+text+'</div>'
}
ZZSWidget.getResult = function(id,t){
var result = {"value":"","type":""}
var tar = document.getElementById(id);
if(!tar) return result;
if(tar.getElementsByClassName("ZZSWidgetOutput")){
tar = tar.getElementsByClassName("ZZSWidgetOutput")[0];
result["type"] = tar.getAttribute("ZZSWidgetType");
if(tar.getAttribute("ZZSWidgetType")=="Button"){return null}
if(tar.tagName=="INPUT" || tar.tagName == "TEXTAREA"){
result["value"] = tar.value;
}else{
result["value"] = tar.innerText;
}
var onlytips = tar.getAttribute("onlytips")
if((onlytips==="true"||onlytips===true) && tar.getAttribute("placeholder")==tar.innerText){
result["value"] = "";
}
}
if(t=="value"||t=="val") return result["value"];
if(t=="type") return result["type"];
return result;
}
ZZSWidget.setValue = function(id,v){
var tar = document.getElementById(id);
if(!tar) return;
if(tar.getElementsByClassName("ZZSWidgetOutput")){
tar = tar.getElementsByClassName("ZZSWidgetOutput")[0];
switch(tar.getAttribute("ZZSWidgetType")){
case "Input":
case "Textarea":
tar.value = v;
break
case "Option":
case "MultipleOption":
case "Calendar":
tar.innerHTML = v;
break
case "Button":
default:
break
}
}
}
ZZSWidget.setWidgetParentNode = function(id){
if(ZZSWidget.isDOM(id)){
ZZSWidget.widgetParentNode = id;
}
else if(document.getElementById(id)){
ZZSWidget.widgetParentNode = document.getElementById(id);
}else{
return;
}
ZZSWidget.widgetParentNode.style.position = "relative";
}
document.addEventListener("click",function(e){
if(document.getElementById("ZZSWidget") && e.target.className.indexOf("ZZSWidgetUnit")<0){
document.getElementById("ZZSWidget").remove();
}
})
上面是我写的ZZSWidget.js的代码,下面是用法demo
<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<body style="width:100%;height:100%;margin:0;padding:0;overflow:hidden;">
<div style="font-weight:bold;width:100%;height:50px;background-color:dodgerblue;text-align:center;line-height:50px;color:white;">ZZSWidget控件demo</div>
<div style="overflow-y:scroll;color:black;" id="demo">
<div id="s" style="background-color:#eee;height:300px;">这个将绑定按钮</div>
<button onclick='ZZSButton("s",function(){alert(1)},{text:"按钮",width:40,height:40,borderRadius:6})'>点击绑定按钮控件到上方</button>
<button onclick='alert(ZZSWidget.getResult("f","value"))'>点击获取输入框控件的值</button>
<br/><br/><br/><br/><br/><br/>
<div id="a" style="background-color:#eee;">这个将绑定单选</div>
<button onclick='ZZSOption("a",[1,2,3,4,5],{offsetHeight:20,placeholder:"这是提示,请选择单选值",onlytips:true})'>点击绑定单选控件到上方</button>
<button onclick='alert(ZZSWidget.getResult("a","value"))'>点击获取单选控件的值</button>
<br/><br/><br/><br/><br/><br/>
<div id="b" style="background-color:#eee;">这个将绑定多选</div>
<button onclick='ZZSMultipleOption("b",[1,2,3,4,5],{offsetHeight:20,placeholder:"这是提示,请选择多选值",onlytips:true})'>点击绑定多选控件到上方</button>
<div id="c" style="background-color:#eee;">这个将绑定日历</div>
<button onclick='alert(ZZSWidget.getResult("b","value"))'>点击获取多选控件的值</button>
<br/><br/><br/><br/><br/><br/>
<button onclick='ZZSCalendar("c",{offsetHeight:20,placeholder:"__today__",onlytips:false})'>点击绑定日历控件到上方</button>
<button onclick='alert(ZZSWidget.getResult("c","value"))'>点击获取日历控件的值</button>
<br/><br/><br/><br/><br/><br/>
<div id="d" style="background-color:#eee;">这个将绑定日历</div>
<button onclick='ZZSCalendar("d",{offsetHeight:20,placeholder:"请选择日期",onlytips:true})'>点击绑定日历控件到上方</button>
<button onclick='alert(ZZSWidget.getResult("d","value"))'>点击获取日历控件的值</button>
<br/><br/><br/><br/><br/><br/>
<div id="e" style="background-color:#eee;">这个将绑定中文文本框</div>
<button onclick='ZZSTextarea("e",{placeholder:"请输入中文",minusWidth:4,minusHeight:-20,onlyinput:"Chinese"})'>点击绑定文本域控件到上方</button>
<button onclick='alert(ZZSWidget.getResult("e","value"))'>点击获取文本域控件的值</button>
<br/><br/><br/><br/><br/><br/>
<div id="f" style="background-color:#eee;">这个将绑定英文输入框</div>
<button onclick='ZZSInput("f",{placeholder:"请输入英文",minusWidth:4,minusHeight:2,onlyinput:"letter"})'>点击绑定输入框控件到上方</button>
<button onclick='alert(ZZSWidget.getResult("f","value"))'>点击获取输入框控件的值</button>
<br/><br/><br/><br/><br/><br/>
</div>
</body>
<script type="text/javascript" src="ZZSWidget.js"></script>
<script type="text/javascript">
document.getElementById("demo").style.height = (window.innerHeight - 50) + "px"
window.addEventListener("resize",function(){
document.getElementById("demo").style.height = (window.innerHeight - 50) + "px"
})
</script>
</html>
该控件库是我在项目中设计的,可以单独使用,不依赖其他库