当前位置: 首页 > news >正文

vue 封装一个鼠标拖动选择时间段功能

 

 

<template><div class="timeRange"><div class="calendar"><table><thead><tr><th rowspan="6" class="weekRow"><b>周/时间</b></th><th colspan="24"><b>00:00 - 12:00</b></th><th colspan="24"><b>12:00 - 24:00</b></th></tr><tr><td colspan="2" v-for="index in 24" :key="index">{{ index - 1 }}</td></tr></thead><tbody @mousemove.prevent="handleMouseMove"><tr v-for="(item, index) in weekDate" :key="index"><td>{{ item }}</td><td class="calendar-atom-time" v-for="i in 48" :key="index + '-' + i":class="{ 'active': selectCells[`${index}_${i}`] }" @mousedown.prevent="handleMouseDown(index, i, $event)"@mouseup.prevent="handleMouseUp(index, i)"></td></tr><div id="box" v-show="moveStartEvent"></div></tbody></table><div class="table-core"><div class="clearfix"><span class="pull-left tip-text">可拖动鼠标选择时间段</span><button class="clearBtn" @click="handleClear">清除所有</button></div><ul><li v-for="(item, index) in selectDate" :key="index" v-if="item.data && item.data.length"><label>{{ item.label }}</label><span v-for="o in item.data" :key="o">{{ o[0] }}~{{ o[1] }}</span></li></ul></div></div></div>
</template><script>
export default {name: 'timeRange',data () {return {// 表列weekDate: ['一', '二', '三', '四', '五', '六', '日'],// 所选格子selectCells: {},// 所选时间数据(做提交时使用)selectDate: {},// 记录鼠标位置moveStartEvent: false,moveStartColumn: 0, // 列moveStarRow: 0, // 行moveStartX: 0,moveStartY: 0}},created () {},mounted () {},methods: {// 初始init (data) {if (data && data instanceof Object) {this.selectCells = data} else {this.selectCells = {}}this.getSelectDate()},// 按下handleMouseDown (column, row, e) {this.moveStartEvent = truethis.moveStartColumn = columnthis.moveStarRow = rowthis.moveStartX = e.layerXthis.moveStartY = e.layerY},// 松开handleMouseUp (column, row) {if (this.moveStartEvent) {this.moveStartEvent = falseconst X = row - this.moveStarRowconst Y = column - this.moveStartColumnconst checked = !this.selectCells[`${column}_${row}`]if (X > -1 && Y > -1) {const obj = this.clone(this.selectCells)for (let i = this.moveStartColumn; i <= column; i++) {for (let j = this.moveStarRow; j <= row; j++) {var key = `${i}_${j}`if (checked) {obj[key] = checked} else if (obj[key]) {delete obj[key]}}}this.selectCells = objthis.$forceUpdate()this.getSelectDate()}}this.moveStartDay = 0this.moveStarTime = 0},// 滑动中handleMouseMove (e) {if (this.moveStartEvent) {const dom = this.$el.querySelector('#box')const X = e.layerX - this.moveStartXconst Y = e.layerY - this.moveStartYif (X >= 0 && Y >= 0) {dom.style.left = this.moveStartX + 'px'dom.style.top = this.moveStartY + 'px'dom.style.width = X + 'px'dom.style.height = Y + 'px'}}},// 组合时间数据getSelectDate () {const arr = []this.weekDate.forEach((item, index) => {arr.push({label: item,data: []})for (var i = 1; i <= 48; i++) {var o = this.selectCells[`${index}_${i}`]if (o) {var endTime = i / 2var startTime = endTime - 0.5if (startTime < 10) {startTime = '0' + startTime}if (endTime < 10) {endTime = '0' + endTime}startTime += ''endTime += ''if (startTime.indexOf('.5') > -1) {startTime = startTime.replace('.5', ':30')} else {endTime = endTime.replace('.5', ':30')}if (startTime.indexOf(':30') < 0) {startTime += ':00'} else {endTime += ':00'}arr[index].data.push([startTime, endTime])}}})arr.forEach(item => {for (var i = 0; i < item.data.length; i++) {var o = item.dataif (o[i + 1] && o[i][1] === o[i + 1][0]) {o[i + 1][0] = o[i][0]item.data.splice(i, 1)i--}}})this.selectDate = arr},// 清除选择handleClear () {this.selectCells = {}this.getSelectDate()this.$forceUpdate()},// 获取数据getData () {return this.selectDate}}
}
</script><style lang="less" scoped>
.timeRange {user-select: none;position: relative;padding: 10px 0;.calendar {display: inline-block;}table {width: 100%;border-radius: 4px;border-spacing: 0;table-layout: fixed;border-collapse: collapse;thead {th,td {height: 30px;}th {padding: 5px 0;}.weekRow {width: 100px;min-width: 100px;padding: 20px 0}}td,th {outline: 0;border: 1px solid #E3E3E3;font-size: 12px;text-align: center;min-width: 11px;line-height: 1.6em;min-width: 24px;}tbody {position: relative;overflow: hidden;td {height: 20px !important;}}td.active {background: #F60457;}}.table-core {line-height: 2.4em;border: 1px solid #E3E3E3;border-top: 0;overflow: hidden;padding: 10px;.clearfix {color: #8A8A8A;text-align: left;height: 22px;line-height: 22px;margin: 8px 0;display: flex;font-size: 12px;.clearBtn {cursor: pointer;color: #5775F9;font-size: 14px;margin-left: auto;}}ul {li {line-height: 22px;margin-bottom: 5px;label {display: inline-block;min-width: 60px;color: #8A8A8A;text-align: left;}span {font-size: 12px;&::after {content: "、"}&:last-child::after {display: none;}}}}}#box {background: rgba(241, 1, 85, 0.4);pointer-events: none;position: absolute;top: 0;left: 0;}
}
</style>

http://www.lryc.cn/news/102356.html

相关文章:

  • ubuntu22.0安装Barrier局域网共享鼠标键盘
  • ffmpeg常用功能博客导航
  • shopee,lazada,etsy店群如何高效安全的管理
  • 【计算复杂性理论】证明复杂性(八):命题鸽巢原理(Propositional Pigeonhole Principle)的指数级归结下界
  • 使用DataX实现mysql与hive数据互相导入导出
  • 语音转录成文本:AI Transcription for mac
  • [nlp] TF-IDF算法介绍
  • 一些感想,写在8月之前
  • 推动数字经济高质量发展需破解三大挑战
  • Pycharm工具Python开发自动添加注释(详细)
  • RUST 有哪些整型?
  • 【Python 实战】---- 批量识别图片中的文字,存入excel中【使用百度的通用文字识别】
  • 探索前端图片如何携带token进行验证
  • 飞桨AI Studio可以玩多模态了?MiniGPT4实战演练!
  • C++笔记之++i和i++是原子操作吗?
  • Pytest+Allure+Excel接口自动化测试框架实战
  • 阿里云国际版账号注册常见问题汇总
  • Flowable基础
  • 力扣热门100题之合并区间【中等】
  • 机会成本:隐形的手,驱动你的选择
  • win10日程怎么同步到安卓手机?电脑日程同步到手机方法
  • 7月31日每日两题
  • 首期华为云ROMA Connect《企业集成战略与华为数字化之道》高研班在东莞圆满举办
  • JS语法知识点
  • 【设计模式】 策略模式
  • Redis优惠券秒杀超卖问题
  • 14个最强大的建筑设计AI工具
  • Ueditor 百度强大富文本Springboot 项目集成使用(包含上传文件和上传图片的功能使用)简单易懂,举一反三
  • 【NLP】一个使用PyTorch实现图像分类的迁移学习实例
  • 【wsl-windows子系统】安装、启用、禁用以及同时支持docker-desktop和vmware方案