parent
1640029e34
commit
f52f05cb3c
@ -0,0 +1,7 @@
|
||||
.date-container {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.date-container.active {
|
||||
display: block;
|
||||
}
|
||||
@ -0,0 +1,223 @@
|
||||
export interface IDatePickerOption {
|
||||
mountDom?: HTMLElement
|
||||
}
|
||||
|
||||
interface IDatePickerDom {
|
||||
container: HTMLDivElement;
|
||||
title: {
|
||||
preYear: HTMLSpanElement;
|
||||
preMonth: HTMLSpanElement;
|
||||
now: HTMLSpanElement;
|
||||
nextMonth: HTMLSpanElement;
|
||||
nextYear: HTMLSpanElement;
|
||||
};
|
||||
day: HTMLDivElement;
|
||||
menu: {
|
||||
time: HTMLButtonElement;
|
||||
now: HTMLButtonElement;
|
||||
submit: HTMLButtonElement;
|
||||
};
|
||||
}
|
||||
|
||||
export class DatePicker {
|
||||
|
||||
private options: IDatePickerOption
|
||||
private now: Date
|
||||
private dom: IDatePickerDom
|
||||
|
||||
constructor(options: IDatePickerOption = {}) {
|
||||
this.options = {
|
||||
mountDom: document.body,
|
||||
...options
|
||||
}
|
||||
this.now = new Date()
|
||||
this.dom = this._createDom()
|
||||
this._bindEvent()
|
||||
}
|
||||
|
||||
private _createDom(): IDatePickerDom {
|
||||
const datePickerContainer = document.createElement('div')
|
||||
datePickerContainer.classList.add('date-container')
|
||||
// title-切换年月、年月显示
|
||||
const datePickerTitle = document.createElement('div')
|
||||
datePickerTitle.classList.add('date-title')
|
||||
const preYearTitle = document.createElement('span')
|
||||
preYearTitle.classList.add('date-title__pre-year')
|
||||
preYearTitle.innerText = `<<`
|
||||
const preMonthTitle = document.createElement('span')
|
||||
preMonthTitle.classList.add('date-title__pre-month')
|
||||
preMonthTitle.innerText = `<`
|
||||
const nowTitle = document.createElement('span')
|
||||
nowTitle.classList.add('date-title__now')
|
||||
const nextMonthTitle = document.createElement('span')
|
||||
nextMonthTitle.classList.add('date-title__next-month')
|
||||
nextMonthTitle.innerText = `>`
|
||||
const nextYearTitle = document.createElement('span')
|
||||
nextYearTitle.classList.add('date-title__next-year')
|
||||
nextYearTitle.innerText = `>>`
|
||||
datePickerTitle.append(preYearTitle)
|
||||
datePickerTitle.append(preMonthTitle)
|
||||
datePickerTitle.append(nowTitle)
|
||||
datePickerTitle.append(nextMonthTitle)
|
||||
datePickerTitle.append(nextYearTitle)
|
||||
// week-星期显示
|
||||
const datePickerWeek = document.createElement('div')
|
||||
datePickerWeek.classList.add('date-week')
|
||||
const weekList = ['日', '一', '二', '三', '四', '五', '六']
|
||||
weekList.forEach(week => {
|
||||
const weekDom = document.createElement('span')
|
||||
weekDom.innerText = `${week}`
|
||||
datePickerWeek.append(weekDom)
|
||||
})
|
||||
// day-天数显示
|
||||
const datePickerDay = document.createElement('div')
|
||||
datePickerDay.classList.add('date-day')
|
||||
// menu-选择时间、现在、确定
|
||||
const datePickerMenu = document.createElement('div')
|
||||
datePickerMenu.classList.add('date-menu')
|
||||
const timeMenu = document.createElement('button')
|
||||
timeMenu.classList.add('date-menu__time')
|
||||
timeMenu.innerText = '时间'
|
||||
const nowMenu = document.createElement('button')
|
||||
nowMenu.classList.add('date-menu__now')
|
||||
nowMenu.innerText = '此刻'
|
||||
const submitMenu = document.createElement('button')
|
||||
submitMenu.classList.add('date-menu__submit')
|
||||
submitMenu.innerText = '确定'
|
||||
datePickerMenu.append(timeMenu)
|
||||
datePickerMenu.append(nowMenu)
|
||||
datePickerMenu.append(submitMenu)
|
||||
// 构建
|
||||
datePickerContainer.append(datePickerTitle)
|
||||
datePickerContainer.append(datePickerWeek)
|
||||
datePickerContainer.append(datePickerDay)
|
||||
datePickerContainer.append(datePickerMenu)
|
||||
this.options.mountDom!.append(datePickerContainer)
|
||||
return {
|
||||
container: datePickerContainer,
|
||||
title: {
|
||||
preYear: preMonthTitle,
|
||||
preMonth: preMonthTitle,
|
||||
now: nowTitle,
|
||||
nextMonth: nextMonthTitle,
|
||||
nextYear: nextYearTitle
|
||||
},
|
||||
day: datePickerDay,
|
||||
menu: {
|
||||
time: timeMenu,
|
||||
now: nowMenu,
|
||||
submit: submitMenu
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private _bindEvent() {
|
||||
this.dom.title.preYear.onclick = () => {
|
||||
this._preYear()
|
||||
}
|
||||
this.dom.title.preMonth.onclick = () => {
|
||||
this._preMonth()
|
||||
}
|
||||
this.dom.title.nextMonth.onclick = () => {
|
||||
this._nextMonth()
|
||||
}
|
||||
this.dom.title.nextYear.onclick = () => {
|
||||
this._nextYear()
|
||||
}
|
||||
this.dom.menu.time.onclick = () => {
|
||||
this._now()
|
||||
}
|
||||
this.dom.menu.submit.onclick = () => {
|
||||
this.dispose()
|
||||
}
|
||||
}
|
||||
|
||||
private _setNow() {
|
||||
this.now = new Date()
|
||||
}
|
||||
|
||||
private _update() {
|
||||
// 当前年月日
|
||||
const year = this.now.getFullYear()
|
||||
const month = this.now.getMonth() + 1
|
||||
const day = this.now.getDate()
|
||||
this.dom.title.now.innerText = `${year}年 ${String(month).padStart(2, '0')}月`
|
||||
// 日期补差
|
||||
const curDate = new Date(year, month, 0) // 当月日期
|
||||
const curDay = curDate.getDate() // 当月总天数
|
||||
let curWeek = new Date(year, month - 1, 1).getDay() // 当月第一天星期几
|
||||
if (curWeek === 0) {
|
||||
curWeek = 7
|
||||
}
|
||||
const preDay = new Date(year, month - 1, 0).getDate() // 上个月天数
|
||||
// 渲染上个月日期
|
||||
const preStartDay = preDay - curWeek + 1
|
||||
for (let i = preStartDay; i <= preDay; i++) {
|
||||
const dayDom = document.createElement('div')
|
||||
dayDom.classList.add('disable')
|
||||
dayDom.innerText = `${i}`
|
||||
this.dom.day.append(dayDom)
|
||||
}
|
||||
// 渲染当月日期
|
||||
for (let i = 1; i <= curDay; i++) {
|
||||
const dayDom = document.createElement('div')
|
||||
if (i === day) {
|
||||
dayDom.classList.add('active')
|
||||
}
|
||||
dayDom.innerText = `${i}`
|
||||
this.dom.day.append(dayDom)
|
||||
}
|
||||
// 渲染下月日期
|
||||
const nextEndDay = 6 * 7 - curWeek - curDay
|
||||
for (let i = 1; i <= nextEndDay; i++) {
|
||||
const dayDom = document.createElement('div')
|
||||
dayDom.classList.add('disable')
|
||||
dayDom.innerText = `${i}`
|
||||
this.dom.day.append(dayDom)
|
||||
}
|
||||
}
|
||||
|
||||
private _preMonth() {
|
||||
this.now.setMonth(this.now.getMonth() - 1)
|
||||
this._update()
|
||||
}
|
||||
|
||||
private _nextMonth() {
|
||||
this.now.setMonth(this.now.getMonth() + 1)
|
||||
this._update()
|
||||
}
|
||||
|
||||
private _preYear() {
|
||||
this.now.setFullYear(this.now.getFullYear() - 1)
|
||||
this._update()
|
||||
}
|
||||
|
||||
private _nextYear() {
|
||||
this.now.setFullYear(this.now.getFullYear() + 1)
|
||||
this._update()
|
||||
}
|
||||
|
||||
private _now() {
|
||||
this.now = new Date()
|
||||
this._update()
|
||||
}
|
||||
|
||||
private _toggleVisible(isVisible: boolean) {
|
||||
if (isVisible) {
|
||||
this.dom.container.classList.add('active')
|
||||
} else {
|
||||
this.dom.container.classList.remove('active')
|
||||
}
|
||||
}
|
||||
|
||||
public render() {
|
||||
this._setNow()
|
||||
this._update()
|
||||
this._toggleVisible(true)
|
||||
}
|
||||
|
||||
public dispose() {
|
||||
this._toggleVisible(false)
|
||||
}
|
||||
|
||||
}
|
||||
Loading…
Reference in new issue