自定义日期组件

思路: 三个数组分别存放年月日,年数组可以更加自己的需要来设置,比如说直接写死,或者设置当前年份的前后多少年可选(这个需要另外写函数),月份写死就是1-12月,日期数组根据所选年份和月份,通过new Date(年份, 月份, 0).getDate(),获取到当前所选月份的最后一天,从而确定这个月的天数。根据需要设置初始值,一般都是设置当前的日期,通过scrollend事件来设置滚动后的时间
HTML结构,分三块基本结构一致,分别用来存放年月日,其中mask用来遮挡选中元素的上下两个元素,target就是选中元素所显示的地方

         <div class="scroll-container">
                <div class="target-center"></div>
                <div class="mask"></div>
                <div class="wrapper year-wrapper">
                    <div class="scroll-wrapper">
                    </div>
                </div>
            </div>

script部分
首先是获取到存放年月日的盒子,设置好年月日数组,然后对其进行初始化,然后给年月日的盒子绑定scrollend事件,处理滚动后的值

        let yearWrapper = document.querySelector('.year-wrapper')
        let monthWrapper = document.querySelector('.month-wrapper')
        let dayWrapper = document.querySelector('.day-wrapper')
        let inp = document.querySelector('#inp')
        let box = document.querySelector('.date-box')
        let confirm = document.querySelector('.confirm')
        let cancel = document.querySelector('cancel')
        const yearArr = [2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009,
            2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019,
            2020, 2021, 2022, 2023]
        const monthArr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
        const y = new Date().getFullYear(),
            m = new Date().getMonth() + 1,
            d = new Date().getDate()
        let currentDay = [y, m, d]
        let dayArr = getDayArr(...currentDay)
        let target = ''
        init()
        function init() {
            initDom()
            bindEvent()
        }
        function bindEvent() {
            yearWrapper.addEventListener('scrollend', setCurrentDate.bind(yearWrapper, 'YEAR'), false)
            monthWrapper.addEventListener('scrollend', setCurrentDate.bind(monthWrapper, 'MONTH'), false)
            dayWrapper.addEventListener('scrollend', setCurrentDate.bind(dayWrapper, 'DAY', false))
            inp.addEventListener('click', clickInput, false)
            confirm.addEventListener('click', clickConfirm, false)

        }
        function clickInput() {
            if (!box.className.includes('show')) {
                box.classList.add('show')
            } else {
                box.className = 'date-box'
            }
        }
        function clickConfirm() {
            console.log(currentDay)
            inp.value = currentDay[0] + '-' + currentDay[1] + '-' + currentDay[2]
        }
        function setCurrentDate(type) {
            var wrapper = this
            //   Math.round返回一个数字四舍五入后最接近的整数
            var index = Math.round(wrapper.scrollTop / 50)
            console.log(index * 50, wrapper.scrollTop)
            switch (type) {
                case 'YEAR':
                    currentDay[0] = yearArr[index]
                    dayArr = getDayArr(...currentDay)
                    createItems(dayWrapper, dayArr)
                    break
                case 'MONTH':
                    currentDay[1] = monthArr[index]
                    dayArr = getDayArr(...currentDay)
                    createItems(dayWrapper, dayArr)
                    break
                case 'DAY':
                    currentDay[2] = dayArr[index];
                    break;
                default:
                    break;
            }
            console.log(currentDay)
        }
        function initDom() {
            createItems(yearWrapper, yearArr)
            createItems(monthWrapper, monthArr)
            createItems(dayWrapper, dayArr)
            initCurrentDate(...currentDay)
        }
        function initCurrentDate(year, month, date) {
            // 获取到年月日对应的下标,通过下标设置到顶部的距离
            let yearIndex = yearArr.indexOf(year)
            let monthIndex = monthArr.indexOf(month)
            let dateIndex = dayArr.indexOf(date)
            setScrollToY(yearWrapper, yearIndex)
            setScrollToY(monthWrapper, monthIndex)
            setScrollToY(dayWrapper, dateIndex)
        }
        function setScrollToY(wrapper, index) {
            // scrollTo(x, y) 使界面滚动到给定元素的指定坐标位置。
            wrapper.scrollTo(0, index * 50)
        }
        function createItems(wrapper, arr) {
            let oFrag = document.createDocumentFragment()
            let scrollWrapper = wrapper.querySelector('.scroll-wrapper')
            for (let i = 0; i < 2; i++) {
                oFrag.appendChild(emptyItems())
            }
            arr.forEach(item => {
                const divItem = document.createElement('div')
                divItem.classList.add('item')
                divItem.innerText = item
                divItem.setAttribute('data-num', item)
                oFrag.appendChild(divItem)
            })
            for (let i = 0; i < 2; i++) {
                oFrag.appendChild(emptyItems())
            }
            scrollWrapper.innerHTML = ''
            scrollWrapper.appendChild(oFrag)
        }
        function emptyItems() {
            const oItem = document.createElement('div')
            oItem.classList.add('item')
            return oItem
        }
        function getDayArr(y, m) {
            let count = getCount(y, m)
            let arr = []
            for (let i = 1; i <= count; i++) {
                arr.push(i)
            }
            return arr
        }
        function getCount(y, m) {
            // 当month为0返回本月的最后一天,所以就得到了一个月有多少天
            return new Date(y, m, 0).getDate()
        }
       ![在这里插入图片描述](https://img-blog.csdnimg.cn/97e34c6ca5e1443b939c3578c9cdeea1.png)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值