react学习札记(三)--自己的日历控件
来源:互联网 发布:韩国女主播软件 编辑:程序博客网 时间:2024/06/05 01:18
最近项目因需要一个个性化的日历,用react写了一个日历控件,如图所示
(function(global){flag = 0;var choice;var Calendar = function(div, date, datemoney){this.div = document.getElementById(div);var w = document.documentElement.clientWidth;var h = document.documentElement.clientHeight;this.width = w; this.height = h*3/5;this.date = date;this.div.style.width = this.width + 'px'; //按默认值设置回去this.div.style.height = this.height + 'px';//按默认值设置回去this.datemoney = datemoney;document.getElementById('header_date').innerHTML = this.date.getFullYear() + '年' + (this.date.getMonth() + 1) + '月';};Calendar.prototype['showUI'] = function(){var exist = document.getElementById('day_table');for(var i = 0; i < 42; i++){ var aim = document.getElementById('day'+i); if (aim!=null && 1 == aim.getAttribute('flag')) choice = aim.getAttribute('date'); } //alert(choice);if(!!exist){this.div.removeChild(exist);}var width = this.width, height = this.height, cell = {width: width/7, height: (height -30 - 20)/6}, monthArr = this._monthPanel(this.date);this.div.style.cursor = 'default';this.div.style.fontFamily = '微软雅黑';var CurDate = new Date();var month = CurDate.getMonth()+1;var day = CurDate.getDate();var today;if(month>=10 && day >=10)today = CurDate.getFullYear()+"/"+month+"/"+day;else if(month>=10 && day <10) today = CurDate.getFullYear()+"/"+month+"/0"+day;else if(month<10 && day >= 10)today = CurDate.getFullYear()+"/0"+month+"/"+day;elsetoday = CurDate.getFullYear()+"/0"+month+"/0"+day;var tableDOM = document.createElement('table');tableDOM.id = "day_table";//生成日历表格框架,通过monthArr向其中复制for(var i=0;i<42;i++){var attr_date;var attr_month = monthArr.date[i].getMonth()+1;var attr_day = monthArr.date[i].getDate();if(attr_month>=10 && attr_day >=10)attr_date = monthArr.date[i].getFullYear()+"/"+attr_month+"/"+attr_day;else if(attr_month>=10 && attr_day <10) attr_date = monthArr.date[i].getFullYear()+"/"+attr_month+"/0"+attr_day;else if(attr_month<10 && attr_day >= 10)attr_date = monthArr.date[i].getFullYear()+"/0"+attr_month+"/"+attr_day;elseattr_date = monthArr.date[i].getFullYear()+"/0"+attr_month+"/0"+attr_day;if (i%7 == 0){var trDOM = document.createElement('tr');trDOM.id = "week"+parseInt(i/7);var tdDOM = document.createElement('td');var cellDOM= document.createElement('div');cellDOM.style.width = cell.width + 'px';cellDOM.style.height = cell.height + 'px';cellDOM.setAttribute('flag',"0");cellDOM.setAttribute('date',attr_date); var pDOM = document.createElement('p');if(cellDOM.getAttribute('date') == today){pDOM.innerHTML = monthArr.date[i].getDate()+"今日";pDOM.id = "now";}elsepDOM.innerHTML = monthArr.date[i].getDate();pDOM.style.marginTop = parseInt(cell.width/7)+'px';//pDOM.style.marginBottom = '0';cellDOM.appendChild(pDOM);cellDOM.className = 'day';cellDOM.id = 'day' + i;tdDOM.appendChild(cellDOM);trDOM.appendChild(tdDOM);tableDOM.appendChild(trDOM);}else{var tdDOM = document.createElement('td');var cellDOM= document.createElement('div');cellDOM.style.width = cell.width + 'px';cellDOM.style.height = cell.height + 'px';cellDOM.setAttribute('flag',"0");cellDOM.setAttribute('date',attr_date); //cellDOM.setAttribute('disabled','disabled');var pDOM = document.createElement('p');if(cellDOM.getAttribute('date') == today){pDOM.innerHTML = monthArr.date[i].getDate()+"今日";pDOM.id = "now";}elsepDOM.innerHTML = monthArr.date[i].getDate();pDOM.style.marginTop = parseInt(cell.width/7)+'px';//pDOM.style.marginBottom = '0';cellDOM.appendChild(pDOM);cellDOM.className = 'day';cellDOM.id = 'day' + i;tdDOM.appendChild(cellDOM);trDOM.appendChild(tdDOM);}if(i < monthArr.preLen || i >= monthArr.currentLen + monthArr.preLen){cellDOM.style.color = '#BFBFBF';}}this.div.appendChild(tableDOM);var date;//判断从外部传入的数组,加入日期对应的钱数for(var i = 0; i < 42; i++){ var aim = document.getElementById('day'+i); //alert(this.datemoney); for(date in this.datemoney){ if(aim!=null&&aim.getAttribute("date")==date && date>=today) { //test.style.backgroundColor = "#fedd00"; aim.setAttribute("money",this.datemoney[date]); aim.className = "day hasmoney"; var money = document.createElement('p'); money.className = "money"; money.innerHTML = "¥"+this.datemoney[date]; aim.appendChild(money);//choice.style.border = "2px solid #fedd00";if(choice==aim.getAttribute('date')){aim.style.border = "2px solid #fedd00";aim.setAttribute('flag','1');} } } } //点击日期生成票的张数和总钱数$(".hasmoney").on("click",function(e){var node = e.target;if(node.id.indexOf('day') > -1 && node.className.indexOf('hasmoney') > -1){//callback(node.getAttribute('date'));if(1==node.getAttribute("flag") && flag == 1){node.setAttribute('flag',"0");node.style.border = "1px solid #C8CACC";document.getElementById('number').innerHTML = 0;flag = 0;document.getElementById('total-money').innerHTML = 0; }else if(0==node.getAttribute("flag")&& flag == 0){node.setAttribute('flag',"1");flag = 1;node.style.border = "2px solid #fedd00";document.getElementById('number').innerHTML = 1;document.getElementById('total-money').innerHTML = node.getAttribute('money');}if(0 == flag){document.getElementById('number').innerHTML = 0;document.getElementById('total-money').innerHTML = 0; }}});$(".money").on("click",function(e){var node = e.target.parentNode;if(node.id.indexOf('day') > -1 && node.className.indexOf('hasmoney') > -1){//callback(node.getAttribute('date'));if(1==node.getAttribute("flag") && flag == 1){node.setAttribute('flag',"0");node.style.border = "1px solid #C8CACC";document.getElementById('number').innerHTML = 0;flag = 0;document.getElementById('total-money').innerHTML = 0; }else if(0==node.getAttribute("flag")&& flag == 0){node.setAttribute('flag',"1");flag = 1;node.style.border = "2px solid #fedd00";document.getElementById('number').innerHTML = 1;document.getElementById('total-money').innerHTML = node.getAttribute('money');}if(0 == flag){document.getElementById('number').innerHTML = 0;document.getElementById('total-money').innerHTML = 0; }}});};Calendar.prototype._monthPanel = function(date){//如果传递了Date对象,则按Date对象进行计算月份面板//否则,按照当前月份计算面板var myDate = date || new Date(), year = myDate.getFullYear(), month = myDate.getMonth(), day = myDate.getDate(), week = myDate.getDay(), currentDays = new Date(year, month + 1, 0).getDate(), preDays = new Date(year, month, 0).getDate(), firstDay = new Date(year, month, 1), firstCell = firstDay.getDay() === 0 ? 6 : firstDay.getDay() - 1, bottomCell = 42 - currentDays - firstCell;//前一个月该显示多少天var preMonth = [];for(var p = firstCell; p > 0; p--){preMonth.push(new Date(year, month - 1, preDays - p + 1));}var len = preMonth.length;//本月var currentMonth = [];for(var c = 0; c < currentDays; c++){currentMonth.push(new Date(year, month, c + 1));}//下一个月 var nextMonth = []; for(var n = 0; n < bottomCell; n++){ nextMonth.push(new Date(year, month + 1, n + 1)); } preMonth = preMonth.concat(currentMonth, nextMonth); return { date: preMonth, preLen: len, currentLen: currentMonth.length };};global.Calendar = Calendar;})(window);这段js是生成日历主体内容结构的。
Calendar.prototype._monthPanel这个方法可作为一个api来使用,直接生成当月的天数,以及对应的情况。
var Share = React.createClass({ componentDidMount: function() { var datemoney = new Array();//需要从外部得到的日期价钱对应表 datemoney["2016/03/01"] = "500"; datemoney["2016/03/17"] = "1000"; datemoney["2016/03/25"] = "5400"; datemoney["2016/04/23"] = "4000"; datemoney["2016/04/02"] = "4300"; (function(global){ //var calendar_codeshow = document.getElementById('calendar_codeshow'); var CurDate = new Date(); var year = CurDate.getFullYear(); var month = CurDate.getMonth()+1; var day = CurDate.getDate(); var arr_date; var arr_date_2; for(arr_date in datemoney){ arr_date_2 = arr_date; break; } var date = new Date(arr_date_2); //日历 var calendar = new Calendar('calendar',date,datemoney);// calendar.showUI(); $("#pre").on('click',function(e){ var year = parseInt(date.getFullYear()), month = parseInt(date.getMonth()); if(month == 0){ date = new Date(year - 1, 11, 1); }else{ date = new Date(year, month - 1, 1); } calendar = new Calendar('calendar',date,datemoney);// calendar.showUI(); }); $("#next").on('click',function(e){ var year = parseInt(date.getFullYear()), month = parseInt(date.getMonth()); if(month === 11){ date = new Date(year + 1, 0, 1); }else{ date = new Date(year, month + 1, 1); } calendar = new Calendar('calendar',date,datemoney);// calendar.showUI(); }); $('#add').on("click",function(e){ for(var i=0;i<42;i++){ var aim = document.getElementById('day'+i); if(aim!=null && aim.getAttribute("flag") == 1){ //alert("if"+1 == flag && 1==aim.getAttribute("flag")); //alert("e"+document.getElementById('number').innerHTML); var money = parseInt(aim.getAttribute('money')); if(1 == flag && 1==aim.getAttribute("flag")){ document.getElementById('number').innerHTML++; //alert(document.getElementById('number').innerHTML); var number = parseInt(document.getElementById('number').innerHTML); document.getElementById('total-money').innerHTML = money * number; //callback(money*number,number); } } } }); $('#reduce').on("click",function(e){ if(parseInt(document.getElementById('number').innerHTML)>1){ for(var i=0;i<42;i++){ var aim = document.getElementById('day'+i); if(aim!=null && aim.getAttribute("flag") == 1){ var money = parseInt(aim.getAttribute('money')); document.getElementById('number').innerHTML--; var number = parseInt(document.getElementById('number').innerHTML); //alert(money); document.getElementById('total-money').innerHTML = money * number; //callback(money*number,number); } }} }); $('.submit').on('click',function(e){ var total_money = document.getElementById('total-money').innerHTML; var number = document.getElementById('number').innerHTML; alert(total_money); alert(number); }); })(this); }, render: function(){ return ( <div id="calendar-main"> <div id="header"> <p className = "head-content">选择活动出发日期<button><img className="close" src="http://download.duckr.cn/wechat/service/close_btn.png" /></button></p> </div> <div id="calendar"> <table id ="week_table"> <tr> <td><div>一</div></td> <td><div>二</div></td> <td><div>三</div></td> <td><div>四</div></td> <td><div>五</div></td> <td><div>六</div></td> <td><div>日</div></td> </tr> </table> <table id = "header_table"> <tr> <td><div id = "pre"><<上月</div></td> <td><div id = "header_date"></div></td> <td><div id = "next">下月>></div></td> </tr> </table> </div> <div id="bottom"> <div id ="reduce-add">购买数量 <button className="reduce"><img id="reduce" src="http://download.duckr.cn/wechat/service/minus_ticket.png"/></button> <span className="zhang">张</span><span id="number">0</span> <button className="add"><img id ="add" src="http://download.duckr.cn/wechat/service/add_ticket.png"/></button> </div> <button className="submit">支付(¥<span id="total-money">0</span>)</button> </div> </div> ); } });React.render(React.createElement(Share , null), document.getElementById('content'));这是外部框架的js,也就是在这个js中调用calendar的。
Safari对于js Date函数有一个坑,就是必须用最标准的形式如Date(YYYY/MM/DD),进行初始化,new
Date(
'2011-04-12'
.replace(/-/g,
"/"
))这样就可以。
其他浏览器可以用相对宽松的形式如Date("2012-3-5")这种的都可以解析,很关键!Safari还有很多坑,比如一个在以前提过的,h5media播放器无法自动播放的情况,必须有一个用户的动作才能触发播放。
(在safri on ios里面明确指出等待用户的交互动作后才能播放media,也就是说如果你没有得到用户的action就播放的话就会被safri拦截)
Safari在点击事件(onclick)中还有一个坑,需要给你的dom写一个css样式 cursor:pointer,因为safari认为这才是一个可点击区域。但是好像使用jQuery on绑定的点击事件就没有问题。。
最后还有个布局上的收获,如果需要在底部加一个其他颜色的蒙版,像最上面那个灰黑色蒙版,这时候不能用background-color+opacity,因为这样会使它下面所有的子div都是变透明,而应该在外面大div中使用css3中给出的rgba(0,0,0,0.7),前面三个代表颜色,最后一个代表透明度,用这种方法就是只在父div中有透明度。nice!
关于布局中的居中问题,可以参考下面这段话:
让行内元素水平居中显示,我们需要为其父级元素设置text-align:center,一般这个属性是用于将文字水平居中的,我们的行内元素就相当于一行之内的文字了,所以可以使用这个方法。
让块级元素,水平居中的办法是为块元素本身添加margin:0 auto;这样块级元素的左右边距就是自动的,也就可以在是水平方向上居中了。
不管是inline-block还是block,我们需要理解其居中的原理,是inline-block,就对其父级元素添加text-align:center,是块级元素就对其本身添加margin:0 auto;记住了这些,以后再对元素进行居中,居左,居右的时候就不用担心自己不会啦。
- react学习札记(三)--自己的日历控件
- OWC控件的使用学习札记(三)
- 自己用的日历控件
- react学习札记(一)
- React学习札记
- 学习react的实例1--日历
- react学习札记(二)
- 三款漂亮的js日历控件
- 三款漂亮的js日历控件
- 自己一直使用的一个不错的js日历控件
- 手把手一步步用DataGridView 控件编写属于自己的日历
- 自定义日历控件,可以根据需求定制属于自己的日历
- OWC控件的使用学习札记(一)
- OWC控件的使用学习札记(二)
- javascript 日期日历控件 三
- c++学习札记(三)
- 树莓派学习札记(三)
- Python3 学习札记(三)
- case class与case object实战
- appcompat_v7/res/values-v21/themes_base.xml No resource found that matches the given name: androidXX
- 打印非负整数阶乘的函数
- 求字符串长度
- 基于DES加密的TCP聊天程序
- react学习札记(三)--自己的日历控件
- 模式匹配基本语法与在集合中的使用
- [POJ 1201]Intervals[差分约束]
- linux 扫描端口
- 第4周项目4程序分析(1)
- 第三次上机上机实践项目-项目5-(1)
- LeetCode-78-Subsets(回溯法)-Medium
- Python常用内置函数
- vsftpd的虚拟账户配置