zoukankan      html  css  js  c++  java
  • vue日历/日程提醒/html5本地缓存

    先上图

    功能:

    1、上拉日历折叠,展示周

    2、左右滑动切换月

    2、“今天”回到今天;“+”添加日程

    3、localStorage存储日程

    index,html

    <body>
      <div id="app" v-cloak @mousedown="down" @mouseup="heightChange">
        <!--日历-->
        <div id="calendar">
          <!-- 年份 月份 -->
          <div class="year-month">
            <span class="add" @click="eventAdd">+</span>
            <span class="choose-yearMonth" >{{ currentYear }}-{{currentMonth}}</span>
            <span class="today" @click="backToday">今天</span>
          </div>
          <div class="clear"></div>
    
    
          <!-- 星期 -->
          <ul class="weekdays">
            <li style="color:red"></li>
            <li></li>
            <li></li>
            <li></li>
            <li></li>
            <li></li>
            <li style="color:red"></li>
          </ul>
    
    
          <!-- 日期 -->
          <ul class="days" ref="daysBox">
    
            <!--展示月-->
            <li :style="{'display':showMonth==true?'block':'none'}" @touchstart="down" @touchend="move" v-for="day in days"> //移动端点击方法,可切换pc端点击方法,见下
              <!--非本月日期,灰色字体-->
              <span v-if="day.getMonth()+1 != currentMonth" class="other-month">{{ day.getDate() }}</span>
    
              <!--本月日期,正常显示-->
              <span v-else>
                <!--今天,特殊标示-->
                <span v-if="day.getFullYear() == new Date().getFullYear() && day.getMonth() == new Date().getMonth() && day.getDate() == new Date().getDate()" class="active">{{ day.getDate() }}</span>
    
                <!--非今天,正常显示-->
                <span v-else>{{ day.getDate() }}</span>
              </span>
            </li>
    
            <!--展示周-->
            <li :style="{'display':showMonth==true?'none':'block'}" @mousedown="down" @mouseup="move_week" v-for="day in week_day"> //pc端点击方法,可切换移动端点击方法,见上
              <span v-if="day.getMonth()+1 != currentMonth" class="other-month">{{ day.getDate() }}</span>
              <span v-else>
                <!--今天-->
                <span v-if="day.getFullYear() == new Date().getFullYear() && day.getMonth() == new Date().getMonth() && day.getDate() == new Date().getDate()" class="active">{{ day.getDate() }}</span>
                <span v-else>{{ day.getDate() }}</span>
              </span>
            </li>
            <li><i class="mui-icon mui-icon-arrowdown"></i></li>
          </ul>     </div>     <!-- 添加日程 -->     <div id="content" v-if="show">       <div class="nav">         <span class="back" @click="eventAdd_false">返回</span>         <span class="finish" @click="eventAdd_true(id)">完成</span>       </div>       <div class="mui-input-row">         <input type="text" placeholder="日程内容" ref="eventName"/>         <input type="text" placeholder="备注信息" ref="eventInfo"/>         <input type="text" list="cars" placeholder="担任角色" ref="eventRole"/>         <datalist id="cars">           <option value="经办人">           <option value="交办人">           <option value="其他">         </datalist>         <input type="text" v-model="getRemindTime" placeholder="设置提醒时间" @click="timeAdd"/>       </div>       <div class="overlay" v-if="selectTime">         <div id="curtain">           <div class="icon-shell">             <div class="icon-false" @click="setTime_false">X</div>             <div class="icon-true" @click="setTime_true"></div>           </div>           <div class="clear"></div>           <label >日             <input type="number" v-model="currentDay" min="0" />           </label>           <label >时             <input type="number" v-model="currentHour" min="0" />           </label>           <label >分             <input type="number" v-model="currentMinute" min="0" />           </label>         </div>       </div>     </div>     <!--选项卡-->     <div id="box">       <ul class="ul1">         <li v-for="(item,index) in tabtit" v-bind:class="{active:index == num}" @click="tab(index)">           {{item}}         </li>       </ul>       <ul class="ul2">         <li v-for="(main,index) in tabmain" v-show="index == num">           <div v-for="(date,index) in main">             <div class="clear"></div>             <div>{{date.eventName}}</div> <div class="keep-right">{{date.eventTime}}</div>             <div class="clear"></div>             <div>{{date.eventInfo}}</div>             <div class="clear"></div>             <div>{{date.eventRole}}</div> <div class="keep-right" @click="select(index)">...</div>             <div class="clear"></div>             <div class="overlay" v-if="index==selectIndex" @click="closeDiv"></div>             <div v-if="index==selectIndex" class="select-p">               <p>修改</p>               <p>...</p>               <p>...</p>               <p>...</p>               <p>...</p>             </div>           </div>         </li>       </ul>     </div>   </div> </body>

    style.css

    * {
    box-sizing: border-box;
    margin:0;
    padding:0;
    list-style:none;
    }
    a{
    text-decoration: none;
    }
    ul {
    list-style-type: none;
    }
    
    body {
    font-family: Verdana, sans-serif;
    background: #E8F0F3;
    }
    #calendar,#box{
    width:100%;
    margin: 0 auto;
    box-shadow: 0 2px 2px 0 rgba(0,0,0,0.14), 0 3px 1px -2px rgba(0,0,0,0.1), 0 1px 5px 0 rgba(0,0,0,0.12);
    }
    [v-cloak] {
    display:none;
    }
    .year-month {
    position: fixed;
    width: 100%;
    height:50px;
    padding: 15px 0px;
    background: #262626;
    }
    .add{
    width: 15%;
    float: left;
    text-align: center;
    color: white;
    }
    
    .choose-yearMonth{
    position: absolute;
    width: 70%;
    float: left;
    text-align: center;
    color: white;
    }
    
    .today{
    width: 15%;
    text-align: center;
    float: right;
    color: white;
    }
    
    .choose-month {
    text-align: center;
    font-size: 1rem;
    }
    
    .arrow {
    padding: 30px;
    }
    
    .arrow:hover {
    background: rgba(100, 2, 12, 0.1);
    }
    
    .month ul li {
    color: white;
    font-size: 20px;
    text-transform: uppercase;
    letter-spacing: 3px;
    }
    
    .weekdays {
    padding-top:55px;
    background-color: #FFFFFF;
    display: flex;
    flex-wrap: wrap;
    color: #949494;
    justify-content: space-around;
    }
    .weekdays2 {
    width: 100%;
    padding-top:55px;
    background-color: #FFFFFF;
    display: flex;
    position: fixed;
    flex-wrap: wrap;
    color: #949494;
    justify-content: space-around;
    }
    .weekdays li {
    display: inline-block;
    width: 13.6%;
    text-align: center;
    }
    .weekdays2 li {
    display: inline-block;
    width: 13.6%;
    text-align: center;
    }
    
    .days {
    padding: 0;
    background: #FFFFFF;
    margin: 0;
    display: flex;
    flex-wrap: wrap;
    justify-content: space-around;
    }
    .days2 {
    width: 100%;
    position: fixed;
    padding: 0;
    background: #FFFFFF;
    margin: 0;
    display: flex;
    flex-wrap: wrap;
    justify-content: space-around;
    }
    
    .days li {
    list-style-type: none;
    display: inline-block;
    width: 14.2%;
    text-align: center;
    padding-bottom: 10px;
    padding-top: 10px;
    font-size: 1rem;
    color: #000;
    }
    
    .days li .active {
    padding: 6px 10px;
    border-radius: 50%;
    background: #00B8EC;
    color: #fff;
    }
    
    .days li .other-month {
    padding: 5px;
    color: gainsboro;
    }
    
    .days li:hover {
    background: #e1e1e1;
    }
    .li-hidden{
    display:none;
    }
    .li-show{
    display:block;
    }
    .ul1 {
    overflow:hidden;
    
    }
    .ul1 li {
    float:left;
    margin:10px;
    cursor:pointer;
    width: calc(79%/3);
    text-align: center;
    }
    .ul1 li:hover {
    color:#00B8EC;
    }
    .ul2 {
    width: 90%;
    margin: 0 auto;
    }
    .ul2 li {
    border:1px solid #ccc;
    padding:10px;
    width:100%;
    height:1000px;
    }
    .keep-right{
    float: right;
    }
    .select-p{
    /* border: 1px solid black; */
    line-height: 30px;
    padding: 10px;
    width: 50%;
    position: absolute;
    right: 6%;
    background-color: white;
    z-index: 3;
    }
    .select-p p:hover{
    background-color: #E6E6FA;
    }
    .
    .active {
    color:#00B8EC;
    }
    
    
    /* 添加日程样式 */
    #content{
    height:80%;
    position: absolute;
    top: 0;
    right: 10%;
    bottom: 0;
    left: 10%;
    margin: auto;
    background-color: wheat;
    }
    .nav{
    width: 100%;
    height:50px;
    margin-bottom: 20px;
    padding:20px;
    }
    .back{
    width:15%;
    height:30px;
    line-height:30px;
    text-align: center;
    background-color: gray;
    border-radius: 25px;
    float: left;
    color: white;
    }
    .finish{
    width: 15%;
    height:30px;
    line-height:30px;
    background-color: red;
    border-radius: 25px;
    text-align: center;
    float: right;
    color: white;
    }
    .overlay{
    position:fixed;
    width:100%;
    height:100%;
    top:0;
    left:0;
    background-color:rgba(0,0,0,0.2);
    z-index:2;
    }
    #curtain{
    width:80%;
    position: absolute;
    right: 10%;
    left: 10%;
    margin: auto;
    
    background-color:#fff;
    border-radius:2px;
    box-shadow: 0 0 8px rgba(0,0,0,0.2);
    position:fixed;
    bottom: 10%;
    text-align:center;
    }
    .icon-shell{
    width:80%;
    margin: 0 auto;
    }
    .icon-true{
    float: right;
    width: 20px;
    height: 30px;
    border-bottom: 3px solid #00B8EC;
    border-right:3px solid #00B8EC;
    margin: 10px auto;
    transform: rotate(45deg);
    -webkit-transform: rotate(45deg);
    -moz-transform: rotate(45deg);
    -ms-transform: rotate(45deg);
    }
    .icon-true:hover{
    opacity: 0.5;
    }
    .icon-false{
    float: left;
    padding-top: 18px;
    font-size: 1.8em;
    color: red;
    }
    .icon-false:hover{
    opacity: 0.5;
    }
    #curtain label{
    text-transform: uppercase;
    background-color: #f4f4f4;
    width: 30%;
    height: 40%;
    font-size: 1em;
    display: inline-block;
    padding: 10px;
    margin: 10% 0;
    }
    
    #curtain input{
    display: block;
    border: 0;
    font: inherit;
    font-size: 1em;
    padding: 6px;
    outline: none;
    text-align: center;
    width: 100%;
    margin: 10px auto;
    background-color:#fff;
    }
    
    
    .clear{
    clear: both;
    }

     time.js

    new Vue({
    el: '#app',
    data: {
    //日历
    currentYear: 2019,//
    lockYear:2019,//返回当前年
    currentMonth: 1,//
    lockMonth:1,//返回当前月
    currentDay: 1,//
    lockDay:1,//返回当前日
    setDay:1,//取月份默认从一号开始取
    currentWeek: 2,//周几
    setWeek:1,
    days: [],//每月天数
    week_day:[],//每周天数
    today_key:1,//取today所在week为第一个week_day
    scroll:0,//滚动高度
    dayScrollTop:0,//日历需要隐藏的高度
    showMonth:true,//上下拉切换月和周
    
    //日历滑动换月
    startX:0,//触摸点
    endX:0,//松开点
    startY:0,
    endY:0,
    
    //添加提醒设置时间
    currentHour:0,
    currentMinute:0,
    getRemindTime:null,
    eventId:1,
    
    //点击显示
    show:false,
    selectTime:false,
    
    //选项卡
    tabtit: ["已设置提醒", "创建时间", "最后发言时间"],
    tabmain: [new Array(), new Array(), new Array()],
    num: 0,
    selectIndex:-1,
    },
    created() {
    this.initData(null);
    },
    watch: { //渲染完后,获取高度
    days(){
    this.$nextTick(function(){
    
    /* console.log(this.$refs.daysBox.offsetHeight,this.$refs.daysBox.offsetTop); */
    var daysBoxHeight=this.$refs.daysBox.offsetHeight;
    var daysBoxHidden=daysBoxHeight/6*3;
    var daysTop=this.$refs.daysBox.offsetTop;
    this.dayScrollTop=daysTop+daysBoxHidden;
    }); 
    },
    },
    methods: {
    initData(cur) {
    var date;
    if (cur) {
    date = new Date(cur);
    } 
    else {
    date = new Date();
    this.lockYear = date.getFullYear();
    this.lockMonth = date.getMonth()+1 < 10 ? '0'+(date.getMonth()+1) : date.getMonth()+1;
    this.lockDay = date.getDate() <10?'0'+date.getDate():date.getDate();
    }
    
    this.currentDay = date.getDate() <10?'0'+date.getDate():date.getDate();//showMonth=false
    this.currentWeek = date.getDay();
    date.setDate(1);
    this.currentYear = date.getFullYear();
    this.currentMonth = date.getMonth()+1 < 10 ? '0'+(date.getMonth()+1) : date.getMonth()+1;
    /*this.currentWeek = date.getDay(); // 1...6,0*/
    this.setWeek=date.getDay();
    this.currentHour = date.getHours() < 10 ? "0" + date.getHours() : date.getHours();
    this.currentMinute = date.getMinutes() < 10 ? "0" + date.getMinutes() : date.getMinutes();
    var str=this.formatDate(this.currentYear , this.currentMonth, this.currentDay);
    var set_str = this.formatDate(this.currentYear , this.currentMonth, 1);
    /*console.log("today:" + str + "," + this.currentWeek);*/
    this.days.length = 0;
    this.week_day.length=0;
    // 默认1号,从一号开始计算,负数代表上个月天数,超过本月天数为下月天数
    for (var i = this.setWeek; i >= 0; i--) {
    var d = new Date(set_str);
    d.setDate(d.getDate() - i);
    /* console.log(d); */
    this.days.push(d); 
    }
    for (var i = 1; i <= 35 - this.setWeek-1 ; i++) {
    var d = new Date(set_str);
    d.setDate(d.getDate() + i);
    /* console.log(d); */
    this.days.push(d);
    }
    for (var i = this.currentWeek; i >= 0; i--) {
    var d = new Date(str);
    d.setDate(d.getDate() - i);
    /* console.log(d); */
    this.week_day.push(d);
    }
    for (var i = 1; i <= 7 - this.currentWeek-1; i++) {
    var d = new Date(str);
    d.setDate(d.getDate() + i);
    /* console.log(d); */
    this.week_day.push(d);
    }
    this.tabmain[0].length=0;
    for(var i=0;i<localStorage.length-1;i++){
    var key=localStorage.key(i);
    var key_value=JSON.parse(localStorage.getItem(key));
    /* console.log(key,key_value); */
    
    
    this.tabmain[0].push(key_value);
    /* console.log(this.tabmain[0].length); */
    }
    
    
    },
    
    eventAdd(){
    this.show=true; 
    },
    timeAdd(){
    this.selectTime=true; 
    },
    backToday(){
    this.initData(null);
    },
    
    pickPre(year=this.currentYear, month=this.currentMonth) {
    // setDate(0); 上月最后一天
    // setDate(35) date后35天,保证为下个月
    var d = new Date(this.formatDate(year , month , 1));
    d.setDate(0);
    /*console.log(d);*/
    this.initData(this.formatDate(d.getFullYear(),d.getMonth() + 1,1));
    this.currentYear=d.getFullYear();
    this.currentMonth=d.getMonth() + 1;
    },
    pickNext(year=this.currentYear, month=this.currentMonth) {
    var d = new Date(this.formatDate(year , month , 1));
    d.setDate(35);
    /*console.log(d);*/
    this.initData(this.formatDate(d.getFullYear(),d.getMonth() + 1,1));
    this.currentYear=d.getFullYear();
    this.currentMonth=d.getMonth() + 1;
    },
    pickPre_week(year=this.currentYear, month=this.currentMonth,day=this.currentDay) {
    // setDate(0); 上月最后一天
    // setDate(35) date后35天,保证为下个月
    var d = new Date(this.formatDate(year , month , day));
    d.setDate(d.getDate()-7);
    /*console.log(d);*/
    this.initData(this.formatDate(d.getFullYear(),d.getMonth() + 1,d.getDate()));
    this.currentYear=d.getFullYear();
    this.currentMonth=d.getMonth() + 1;
    this.currentDay=d.getDate();
    },
    pickNext_week(year=this.currentYear, month=this.currentMonth,day=this.currentDay) {
    var d = new Date(this.formatDate(year , month , day));
    d.setDate(d.getDate()+7);
    console.log(d);
    this.initData(this.formatDate(d.getFullYear(),d.getMonth()+1,d.getDate()));
    this.currentYear=d.getFullYear();
    this.currentMonth=d.getMonth()+1;
    this.currentDay=d.getDate();
    console.log(this.currentYear,this.currentMonth,this.currentDay);
    },
    
    down(event){
    this.startX=event.clientX;
    this.startY=event.clientY;
    },
    move(event){
    this.endX=event.clientX;
    if((this.startX-this.endX)>0){
    console.log('zuohua');
    this.pickNext(this.currentYear, this.currentMonth);
    }
    if((this.startX-this.endX)<0){
    this.pickPre(this.currentYear, this.currentMonth);
    console.log('youhua');
    }
    /*alert('滑动成功');*/ 
    },
    move_week(event){
    
    this.endX=event.clientX;
    if((this.startX-this.endX)>0){
    this.pickNext_week(this.currentYear, this.currentMonth);
    }
    if((this.startX-this.endX)<0){
    this.pickPre_week(this.currentYear, this.currentMonth);
    }
    },
    heightChange(){
    this.endY=event.clientY;
    if(this.scroll>0){
    this.showMonth=false;
    this.scroll=0;
    }
    if(this.scroll<0){
    this.showMonth=true;
    }
    
    },
    
    // 返回 类似 YYYY-MM-DD 格式的字符串
    formatDate(year,month,day){
    var y = year;
    var m = month;
    if(m<10) {
    m = "0" + m;
    }
    var d = day;
    if(d<10) {
    d = "0" + d;
    }
    return y+"-"+m+"-"+d
    },
    
    eventAdd_false(){
    this.show=false;
    },
    eventAdd_true(id=this.eventId){
    /* var id = localStorage.getItem(this.eventId); */
    var name=this.$refs.eventName.value;
    var info=this.$refs.eventInfo.value;
    var role=this.$refs.eventRole.value;
    var time=this.getRemindTime;
    if(name && info && role &&time){
    var event={"eventName":name,"eventInfo":info,"eventRol":role,"eventTime":time}
    localStorage.setItem(id,JSON.stringify(event));
    /* console.log(localStorage.length); */
    this.eventId++;
    this.tabmain[0].push(event);
    this.show=false;
    /* alert('name'+':'+name +'info'+':'+info +'role'+':'+role +'time'+':'+time + '设置成功'); */
    }
    else{
    alert('输入不能为空');
    }
    /* console.log(localStorage.getItem("eventId")); */
    },
    
    setTime_false(){
    this.selectTime=false;
    },
    setTime_true(){
    this.selectTime=false;
    this.getRemindTime=this.currentYear + "-" +this.currentMonth + "-" +this.currentDay + " " +this.currentHour + ":" +this.currentMinute + ":00";
    },
    
    tab(index) {
    this.num = index;
    },
    select(index){
    this.selectIndex=index;
    },
    closeDiv(){
    
    this.selectIndex=-1;
    },
    menu() {
    this.scroll = document.documentElement.scrollTop || document.body.scrollTop;
    
    /* console.log(this.scroll,this.dayScrollTop); */
    
    
    /* if (document.documentElement.scrollTop > 200) { 
    alert('页面高度大于200执行操作')
    } else {
    alert('页面高度xiao于200执行操作')
    } */
    /* console.log(document.getElementsByClassName('days').offsetHeight);
    console.log(document.documentElement.scrollTop) */
    /* console.log(this.$refs.elements.value); */
    },
    eventScroll(){
    if(this.scroll-this.dayScrollTop>0){
    var date = new Date();
    this.currentYear=date.getFullYear();
    this.currentMonth = date.getMonth()+1 < 10 ? '0'+(date.getMonth()+1) : date.getMonth()+1;
    this.currentWeek=date.getDay();
    for (var i = this.currentWeek; i >= 0; i--) {
    date.setDate(date.getDate() - i);
    /* console.log(d); */
    this.week_day.push(date);
    }
    this.showMonth=false;
    /* alert('ok'); */
    }
    else{
    
    }
    }
    },//methods
    
    mounted() {
    window.addEventListener('scroll', this.menu);
    },
    
    destroyed () {
    window.removeEventListener('scroll', this.menu)
    },
    
    });///new Vue
  • 相关阅读:
    bzoj 2002 [Hnoi2010]Bounce 弹飞绵羊
    【无图慎入】Link Cut Tree 总结
    cogs1889 [SDOI2008]Cave 洞穴勘测 link-cut tree
    Codeforces Round #452 (Div. 2)
    【正经向】NOIP2017烤后总结
    cogs1772 [国家集训队2010]小Z的袜子
    noip2017普及题解
    noip2017 TG 游记
    noip2017 PJ AK记
    jzoj5341 捕老鼠
  • 原文地址:https://www.cnblogs.com/tenfly/p/11446023.html
Copyright © 2011-2022 走看看