思路: 三个数组分别存放年月日,年数组可以更加自己的需要来设置,比如说直接写死,或者设置当前年份的前后多少年可选(这个需要另外写函数),月份写死就是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)