LunuZ

问题

项目中希望elementUI 的DateTimePicker达到与TimePicker相同的固定时间点,即设置步长的效果,但elementUI目前并未提供此功能,所以我自己用dom的方式实现改功能

代码实现

vue部分

<template>
  <div>
    <el-date-picker
        time-arrow-control
        :id="\'dp-step-5minute-id_\'+randId"
        :popper-class="\'dp-step-5minute dp-step-5minute-id_\'+randId"
        v-model="value"
        type="datetime"
        format="yyyy-MM-dd HH:mm:ss"
        value-format="yyyy-MM-dd HH:mm:ss"
        placeholder="选择日期时间">
    </el-date-picker>
    <el-date-picker
        time-arrow-control
        :id="\'dp-step-5minute-id_\'+randId1"
        :popper-class="\'dp-step-5minute dp-step-5minute-id_\'+randId1"
        v-model="value1"
        type="datetime"
        format="yyyy-MM-dd HH:mm:ss"
        value-format="yyyy-MM-dd HH:mm:ss"
        placeholder="选择日期时间1">
    </el-date-picker>

    <br>
    <br>
    <el-button @click="alertPickerValue">获取数据</el-button>
  </div>
</template>

<script>
import func_DatePicker from \'../utils/set_dp-step-5minute\'
export default {
  name: \'demo\',
  data() {
    return {
      value: "2021-07-30 12:45:45",
      value1: "2021-07-30 2:05:33",
      randId:new Date().getTime(),
      randId1:new Date().getTime() + 10
    };
  },
  destroyed() {
    // 注销事件
  },
  mounted(){
    const _this = this
    try {
      document.body.addEventListener(\'click\', (e) => {
        func_DatePicker(e, function() {
          const timePicker = document.getElementById(\'dp-step-5minute-id_\' + _this.randId)
          const timePicker1 = document.getElementById(\'dp-step-5minute-id_\' + _this.randId1)
          _this.value = timePicker.value
          _this.value1 = timePicker1.value
        })
      }, true)
    } catch (e) {
      console.log(e)
    }
  },
  methods:{
    alertPickerValue(){
      alert(this.value)
      alert(this.value1)
    }
  }
}
</script>

 

set_dp-step-5minute.js文件

const func_DatePicker = function(e,callBack){
    const { type,target,path} = e
    const flag = path.findIndex(v => v.className && v.className.indexOf(\'dp-step-5minute\')>-1)// 判断是点击事件且是dp-step-5minute类
    if(type === \'click\' && (flag > -1)) {
        // 已绑定事件的容器做标记,用于防止重复绑定
        const container = getDateContainer(target)
        const isBindClick = container.getAttribute(\'isBindClick\')
        if(isBindClick) return false
        container.setAttribute(\'isBindClick\',true)
        const wrapper = container.querySelector(\'.el-date-picker__time-header .el-date-picker__editor-wrap:nth-child(2)\')
        const spinner = wrapper.querySelector(\'.el-time-panel .el-time-spinner__wrapper:nth-child(2)\')
        const HourSpinner = wrapper.querySelector(\'.el-time-panel .el-time-spinner__wrapper:nth-child(1)\')
        const SecondSpinner = wrapper.querySelector(\'.el-time-panel .el-time-spinner__wrapper:nth-child(3)\')
        const commitBtn = container.querySelector(\'.el-picker-panel__footer button:nth-child(2)\')
        // 当前分钟数
        let currentMinute = 0
        // 移除事件
        // todo......

        // 绑定事件
        // time-spinner
        const spinnerEle = spinner.querySelector(\'.el-time-spinner__list\')

        // time input 绑定click事件 - 初始化数据
        const inputEle = wrapper.querySelector(".el-input__inner")
        const func_inputEle = function(){
            const current = getCurrent()
            setMinute(current)
        }
        inputEle.addEventListener(\'click\',func_inputEle)

        // time input 绑定change事件
        const func_change_inputEle = function(){
            setInputVal()
        }

        // 箭头up绑定事件(上)
        const oldUpEle = spinner.querySelector(".el-icon-arrow-up")
        const newUpEle = createEle(\'i\',\'el-time-spinner__arrow el-icon-arrow-up\',\'\')
        oldUpEle.parentNode.replaceChild(newUpEle,oldUpEle);
        const func_upEle = function(){
            const current = getCurrent()
            setMinute(current,\'up\')
        }
        newUpEle.addEventListener(\'click\',func_upEle)
        // 箭头down绑定事件(下)
        const oldDownEle = spinner.querySelector(".el-icon-arrow-down")
        const newDownEle = createEle(\'i\',\'el-time-spinner__arrow el-icon-arrow-down\',\'\')
        oldDownEle.parentNode.replaceChild(newDownEle,oldDownEle);
        const func_downEle = function(){
            const current = getCurrent()
            setMinute(current,\'down\')
        }
        newDownEle.addEventListener(\'click\',func_downEle)

        // 小时、秒 上下箭头触发input的change
        const h_DownEle = HourSpinner.querySelector(".el-icon-arrow-down")
        const h_UpEle = HourSpinner.querySelector(".el-icon-arrow-up")
        const S_DownEle = SecondSpinner.querySelector(".el-icon-arrow-down")
        const S_UpEle = SecondSpinner.querySelector(".el-icon-arrow-up")
        h_DownEle.addEventListener(\'click\',func_change_inputEle)
        h_UpEle.addEventListener(\'click\',func_change_inputEle)
        S_DownEle.addEventListener(\'click\',func_change_inputEle)
        S_UpEle.addEventListener(\'click\',func_change_inputEle)

        // 绑定确定按钮点击事件
        const func_commitBtn = function () {
            const resultInput = getResultInput(container)
            const timeVal = inputEle.value
            const value = resultInput.value
            resultInput.value = value.split(" ")[0]+" "+timeVal
            callBack()
        }
        commitBtn.addEventListener(\'click\',func_commitBtn)
        // 获取当前分钟数
        // eslint-disable-next-line no-inner-declarations
        function getCurrent(){
            const timeVal = inputEle.value
            let current = 0
            if(timeVal){
                const minute = Number(timeVal.split(":")[1])
                if(minute % 5 === 0)current = minute
            }
            return Number(current)
        }
        // 设置time-spinner的html,并计算返回current
        // eslint-disable-next-line no-inner-declarations
        function setMinute(current,type){
            if(type === \'down\') {
                if(current === 55) {current = 55} //到低了,还是当前值
                else current = current + 5
            }else if(type === \'up\') {
                if(current === 0) {current = 0} //到头了,还是当前值
                else current = current - 5
            }
            let html = \'\'
            if(current === 0){
                html = `<li class="el-time-spinner__item"></li>
            <li class="el-time-spinner__item active">0</li>
            <li class="el-time-spinner__item">5</li>`
            }else if(current === 55){
                html = `<li class="el-time-spinner__item">50</li>
            <li class="el-time-spinner__item active">55</li>
            <li class="el-time-spinner__item"></li>`
            }else{
                html = `<li class="el-time-spinner__item">${current-5}</li>
            <li class="el-time-spinner__item active">${current}</li>
            <li class="el-time-spinner__item">${Number(current)+5}</li>`
            }
            spinnerEle.innerHTML = html
            currentMinute = current
            setInputVal()
        }
        // 设置input分钟数的值
        // eslint-disable-next-line no-inner-declarations
        function setInputVal() {
            const timeVal = inputEle.value
            let arr = [\'00\',\'00\',\'00\']
            if(timeVal){
                arr = timeVal.split(":")
            }
            arr[1] = currentMinute<10 ? \'0\'+currentMinute : currentMinute
            inputEle.value = arr.join(\':\')
        }
        // 创建节点
        // eslint-disable-next-line no-inner-declarations
        function createEle(type,classname,text){
            const element = document.createElement(type);
            element.className = classname;
            const textNode = document.createTextNode(text);
            element.appendChild(textNode);
            return element
        }
    }

    // 公共方法
    function getDateContainer(target){
        const className = target.className
        if(className.indexOf(\'dp-step-5minute\')>-1) {
            return target
        }else{
            return getParents(target, \'dp-step-5minute\')
        }

    }
    function getParents(el, parentsClass) {
        while(el.parentNode){
            el = el.parentNode
            if(el.className.indexOf(parentsClass)>-1) {
                return el
            }
        }
        return null;
    }
    function getResultInput(container) {
        const classList = container.classList
        let id = \'\'
        classList.forEach(v => {
            if(v.startsWith(\'dp-step-5minute-id\')) id = v
        })
        const result = document.getElementById(`${id}`)
        return result
    }
}
export default func_DatePicker

 

最终展示

 

分类:

技术点:

相关文章:

  • 2021-10-28
  • 2021-11-20
  • 2021-11-01
  • 2021-11-21
  • 2021-10-23
  • 2021-05-29
  • 2021-10-14
猜你喜欢
  • 2022-02-19
  • 2022-12-23
  • 2021-12-31
  • 2021-09-24
  • 2021-10-17
  • 2021-05-15
  • 2022-12-23
相关资源
相似解决方案