基于moment写一个滑动日历

2018-09-14 admin

效果如图(日期可左右滑动) clipboard.png

思路: 1、先得到相邻三个周的数据,初始化的时候讲容器向左移动一个视口的距离,确保中间周在可视范围(在可是范围的所用为1) 2、触摸移动阶段,比如向左移动,相当于改变可是范围的索引,也就是2,即向左移动过两个视口的范围 3、移动结束,这时右边已经没有待显示的数据,需要重组数据,再向后加一周,使当前显示的周在中间,同时需要改变显示的索引为1

在当前视口内显示本周的7天,由于需要滑动,所以事先还需要把今天以前的一周和以后的一周准备好

let today = moment().format('YYYY-MM-DD') // 当前日期:"2018-09-14"
moment(today).subtract(7, 'd').format('YYYY-MM-DD') // 上一周的今天:"2018-09-07"
moment(today).add(7, 'd').format('YYYY-MM-DD') // 下一周的今天:"2018-09-21"

得到数组: dates clipboard.png

由此数据可以生成三个模板,分别表示上周,本周和下周,再根据此数据,计算上周,本周和下周的详情。

      getDays: function (day) {
        let arr = []
        /* 计算传进来的日期为星期几 */
        let weekOfDate = Number(moment(day).format('E'))
        // 提前定义好的: this.week = ['一', '二', '三', '四', '五', '六', '日']
        for (let i = 0; i < this.week.length; i++) {
          arr.push(
            {
              date: moment(day).subtract(weekOfDate - i - 1, 'd').format('YYYY-MM-DD'),
              week: this.week[i]
            }
          )
        }
        return arr
      }

遍历数组dates。分别传进getDays可的到三周的详情

clipboard.png

然后遍历数组进行页面渲染

            <template v-for="(item, index) in dates">
                <div class="slider">
                    <div class="day" v-for="(day, dayIndex) in getDays(item.date)">
                        <div :class="{today: day.date === defaultDate}">{{day.date.split('-')[2]}}</div>
                    </div>
                </div>
            </template>

这里,静态显示已经完成

为组件添加滑动功能

改写上方的页面渲染代码

   <div class="week-slider">
        <div
            class="sliders"
            ref="sliders"
            @touchstart="touchStart"
            @touchmove="touchmove"
            // 初始样式,应该向饰扣左方移动一个视口的距离,确保当前周在中间
            :style="getTransform" 
            @touchend="touchend"
            @webkit-transition-end="transitionEnd"
            @transitionend="transitionEnd">
            <template v-for="(item, index) in dates">
                <div class="slider">
                    <div class="day" v-for="(day, dayIndex) in getDays(item.date)">
                        <div :class="{today: day.date === defaultDate}">{{day.date.split('-')[2]}}</div>
                    </div>
                </div>
            </template>
        </div>
    </div>
     // actIndex: 当前活动视图的缩影,初始为1,sliderWidth:视口的宽度, distan: {x:0, y: 0}: 触摸移动的距离
     // 
     getTransform: function () {
        this.endx = (-this.actIndex * this.sliderWidth)  + this.distan.x
        let style = {}
        style['transform'] = 'translateX(' + this.endx + 'px)'
        // 这一条必须写,因为触摸移动的时候需要过渡动画,但是在动画结束重组数据的时候需要瞬间回到该去的位置,不能要过渡动画
        style['transition'] = this.isAnimation ? 'transform .5s ease-out' : 'none'
        return style
      }

最后触摸时间处理:

      touchStart: function (e) {
        this.start.x = e.touches[0].pageX
      },
      touchmove: function (e) {
        // 这里需要过渡动画
        this.isAnimation = true
        this.distan.x = e.touches[0].pageX - this.start.x
        // 需要移动的容器
        let dom = this.$refs.sliders
        // 向左
        this.endx = this.endx + this.distan.x
        dom.style['transform'] = 'translateX('+ this.endx + 'px)'
      },
      touchend: function (e) {
        this.isAnimation = true
        this.distan.x = e.changedTouches[0].pageX - this.start.x
        // 向右
        if (this.distan.x > 0) {
          this.direction = 'right'
          this.actIndex = 0
        } else if (this.distan.x < 0) {
          this.direction = 'left'
          this.actIndex = 2
        }
        this.distan.x = 0
      },

过渡结束后重置容器位置

// 过渡结束
      transitionEnd: function () {
        this.isAnimation = false
        if (this.actIndex === 2) {
            this.dates.push({
                date: moment(this.dates[this.actIndex].date).add(7, 'd').format('YYYY-MM-DD')
            })
            this.dates.shift()
            this.actIndex = 1
        }else if (this.actIndex === 0) {
            this.dates.unshift({
                date: moment(this.dates[this.actIndex].date).subtract(7, 'd').format('YYYY-MM-DD')
            })
            this.dates.pop()
            this.actIndex = 1
        }
      }

原文链接:https://segmentfault.com/a/1190000016401628

本站文章除注明转载外,均为本站原创或编译。欢迎任何形式的转载,但请务必注明出处。

转载请注明:文章转载自 JavaScript中文网 [https://www.javascriptcn.com]

本文地址:https://www.javascriptcn.com/read-40290.html

文章标题:基于moment写一个滑动日历

相关文章
jscript读写二进制文件的方法
本文实例讲述了jscript读写二进制文件的方法。分享给大家供大家参考。具体实现方法如下: var bin = new Array(256); for(var i=0;i&lt;256;i++){ bin[i]=String.fromC...
2017-03-22
[翻译]基于Webpack4使用懒加载分离打包React代码
原文地址:https://engineering.innovid.com/code-splitting-using-lazy-loading-with-react-redux-typescript-and-webpack-4-3ec601...
2018-03-11
JS基于cookie实现来宾统计记录访客信息的方法
&lt;p&gt;本文实例讲述了JS基于cookie实现来宾统计记录访客信息的方法。分享给大家供大家参考。具体如下:&lt;/p&gt;&lt;p&gt;这里使用JavaScript记录访客的来宾信息,记录是第几次来访,显示的信息有:您的名...
2017-03-29
基于javascript实现单选及多选的向右和向左移动实例
本文实例讲述了基于javascript实现单选及多选的向右和向左移动实例。分享给大家供大家参考。具体实现方法如下: 方法 一: &lt;body&gt; &lt;h1&gt;实现单选及多选的向右和向左移动&lt;&#x2F;h1&gt; &...
2017-03-27
基于Marquee.js插件实现的跑马灯效果示例
本文实例讲述了基于Marquee.js插件实现的跑马灯效果。分享给大家供大家参考,具体如下: 1、Marquee.js文件 &#x2F;****************************************************...
2017-02-17
javascript实现英文首字母大写
方法一: function replaceStr(str){ &#x2F;&#x2F; 正则法 str = str.toLowerCase(); var reg = &#x2F;\b(\w)|\s(\w)&#x2F;g; &#x2F;&...
2017-03-22
JavaScript实现基于Cookie的存储类实例
本文实例讲述了JavaScript实现基于Cookie的存储类。分享给大家供大家参考。具体分析如下: 通过这个JS类,你可以象使用session一样使用cookie,非常简单了! &#x2F;* * CookieStorage.js *...
2017-03-22
使用JavaScript制作一个简单的计数器的方法
设计思想 该方法的关键是Cookie技术和动态图像特性的综合运用。使用Cookie,可以在用户端的硬盘上记录用户的数据,下次访问此站点时,即可读取用户端硬盘的Cookie,直接得知来访者的身份和访问次数等有关信息。JavaScript中通过...
2017-03-27
JavaScript数组对象实现增加一个返回随机元素的方法
本文实例讲述了JavaScript数组对象实现增加一个返回随机元素的方法。分享给大家供大家参考。具体如下: 核心特性: 概率随机、顺序随机、随机冒泡 本方法 来自个人手写 JavaScript 的实践,只涉及 JavaScript 1.5(...
2017-03-27
JavaScript使用pop方法移除数组最后一个元素用法实例
本文实例讲述了JavaScript使用pop方法移除数组最后一个元素的用法。分享给大家供大家参考。具体如下: 下面的代码演示了JS数组的pop方法,可以用来移除数组的最后一个元素,实际上就是把数组当成堆栈使用 &lt;!DOCTYPE ht...
2017-03-22
回到顶部