<template>
<div class="byted-weektime">
<div class="calendar">
<!-- <div class="schedule"></div> -->
<!-- <div class="schedule" style="opacity: 0; display: none; left: 680px; top: 294px; width: 11px; height: 30px;"></div> -->
<table class="calendar-table" style="width:810px">
<thead class="calendar-head">
<tr>
<th rowspan="10" class="week-td">星期/时间</th>
<th colspan="12">00:00 - 06:00</th>
<th colspan="12">06:00 - 12:00</th>
<th colspan="12">12:00 - 18:00</th>
<th colspan="12">18:00 - 24:00</th>
</tr>
<!-- <tr>
<td colspan="2" v-for="index in tableHeader">{{ index }}</td>
</tr> -->
</thead>
<tbody @mousemove.prevent.stop="kuangMove" @mouseleave.prevent.stop="kuangLeave" @mousedown.prevent.stop="kuangDown" @mouseup.prevent.stop="kuangUp">
<!-- 不画框,没bug -->
<!-- <tbody id="tableBody"> -->
<div id="kuang"
:style="{ width: kuangObj.width + 'px', height: kuangObj.height + 'px', top: kuangObj.top + 'px', left: kuangObj.left + 'px', bottom: kuangObj.bottom + 'px', right: kuangObj.right + 'px' }">
</div>
<tr>
<td>星期一</td>
<td @mousedown.prevent="handleMouseDown(i, 0)" @mouseup.prevent="handleMouseUp(i, 0)"
class="calendar-atom-time" :class="item.class" v-for="(item, i) in rowUnit[0]"></td>
</tr>
<tr>
<td>星期二</td>
<td @mousedown.prevent="handleMouseDown(i, 1)" @mouseup.prevent="handleMouseUp(i, 1)"
class="calendar-atom-time" :class="item.class" v-for="(item, i) in rowUnit[1]"></td>
</tr>
<tr>
<td>星期三</td>
<td @mousedown.prevent="handleMouseDown(i, 2)" @mouseup.prevent="handleMouseUp(i, 2)"
class="calendar-atom-time" :class="item.class" v-for="(item, i) in rowUnit[2]"></td>
</tr>
<tr>
<td>星期四</td>
<td @mousedown.prevent="handleMouseDown(i, 3)" @mouseup.prevent="handleMouseUp(i, 3)"
class="calendar-atom-time" :class="item.class" v-for="(item, i) in rowUnit[3]"></td>
</tr>
<tr>
<td>星期五</td>
<td @mousedown.prevent="handleMouseDown(i, 4)" @mouseup.prevent="handleMouseUp(i, 4)"
class="calendar-atom-time" :class="item.class" v-for="(item, i) in rowUnit[4]"></td>
</tr>
<tr>
<td>星期六</td>
<td @mousedown.prevent="handleMouseDown(i, 5)" @mouseup.prevent="handleMouseUp(i, 5)"
class="calendar-atom-time" :class="item.class" v-for="(item, i) in rowUnit[5]"></td>
</tr>
<tr>
<td>星期日</td>
<td @mousedown.prevent="handleMouseDown(i, 6)" @mouseup.prevent="handleMouseUp(i, 6)"
class="calendar-atom-time" :class="item.class" v-for="(item, i) in rowUnit[6]"></td>
</tr>
<tr>
<td colspan="49" class="td-table-tip">
<div class="clearfix">
<span class="pull-left tip-text">请用鼠标点选时间段</span> <a @click="clear" class="pull-right"> 清空</a>
</div>
</td>
</tr>
<tr>
<td colspan="49" class="timeContent">
<div v-for="(item, index) in timeStr" v-show="item.length">
<span>{{ weekDate[index + 1] }}: </span>
<strong><span>{{ item }}</span></strong>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</template>
<script>
export default {
name: 'timeSelect',
data() {
return {
// tableHeader: ['00', '01', '02', '03', '04', '05', '06', '07', '08', '09', '10', '11', '12', '13', '14', '15', '16', '17', '18', '19', '20', '21', '22', '23'],
weekDate: { '1': '星期一', '2': '星期二', '3': '星期三', '4': '星期四', '5': '星期五', '6': '星期六', '7': '星期日' },
rowUnit: [ //每一个单元格
],
timeContent: [ //选中的时间段原始数据
],
timeSection: [ //时间段,可以返回给后端的数据
],
timeStr: [ //时间段,前端显示的数据
],
beginDay: 0,
beginTime: 0,
downEvent: false,
kuangObj: {
width: 0,
height: 0,
top: 0,
left: 0,
bottom: 0,
right: 0,
oldLeft: 0,
oldTop: 0,
flag: false
}
}
},
created() {
this.init()
},
mounted() {
},
methods: {
init() {
for (let i = 0; i < 7; i++) {
let arr = []
for (let j = 0; j < 48; j++) {
arr.push({ class: null, timeData: j })
}
this.rowUnit.push(arr)
this.timeContent.push({ arr: [] })
this.timeSection.push([])
this.timeStr.push('')
}
},
handleMouseDown(i, day) {
this.downEvent = true //按下时鼠标不在范围内则不算
this.beginDay = day
this.beginTime = i
},
handleMouseUp(i, day) {
//当点击事件是在table内才触发选取数据操作
if (this.downEvent) {
//选时间段
let _this = this
let begin = this.beginTime
let start = begin <= i ? begin : i //x轴 起点
let length = Math.abs(begin - i)
let end = start + length //x轴 终点
let dayStart = this.beginDay <= day ? this.beginDay : day //y轴 起点
let dayLength = Math.abs(this.beginDay - day)
let dayEnd = dayStart + dayLength //y轴 终点
//当框选范围内所有块都是选中状态时,执行反选
function isAdd() {
for (let x = dayStart; x < dayEnd + 1; x++) {
for (let y = start; y < end + 1; y++) {
if (_this.rowUnit[x][y].class == null) return true
}
}
return false
}
if (isAdd()) {
//没选中的全都选上
for (let x = dayStart; x < dayEnd + 1; x++) {
for (let y = start; y < end + 1; y++) {
if (this.rowUnit[x][y].class == null) {
this.rowUnit[x][y].class = 'ui-selected'
this.timeContent[x].arr.push(this.rowUnit[x][y].timeData)
}
}
}
} else { //反选
for (let x = dayStart; x < dayEnd + 1; x++) {
for (let y = start; y < end + 1; y++) {
this.rowUnit[x][y].class = null
this.timeContent[x].arr.remove(this.rowUnit[x][y].timeData)
}
}
}
//过滤时间段,将临近的时间段合并
this.filterTime(dayStart, dayEnd)
}
this.downEvent = false
},
filterTime(start, end) { //选中的x,y坐标信息 x:0-47 y:0-6
function sortCut(arr) { //提取连续的数字
var result = []
arr.forEach(function (v, i) {
var temp = result[result.length - 1];
if (!i) {
result.push([v]);
} else if (v % 1 === 0 && v - temp[temp.length - 1] == 1) {
temp.push(v)
} else {
result.push([v])
}
});
return result
}
function toStr(num) {
if (Number.isInteger(num)) {
let str = num < 10 ? ('0' + num) : num.toString()
return str + ':00'
} else {
let str = Math.floor(num) < 10 ? ('0' + Math.floor(num)) : Math.floor(num).toString()
return str + ':30'
}
}
function timeToStr(arr) { //把数组转成方便人看到字符串
let str = ''
arr.forEach((arr, index) => {
let str1 = ''
if (index == 0) {
str1 = toStr(arr[0]) + '~' + toStr(arr[1])
} else {
str1 = ' , ' + toStr(arr[0]) + '~' + toStr(arr[1])
}
str += str1
})
return str
}
//排序,分割成
for (let i = start; i < end + 1; i++) {
let arr1 = sortCut(this.timeContent[i].arr.sort((a, b) => a - b))
let arr2 = []
arr1.forEach((arr) => { //转成带小数点的时间段,以及供前端显示的字符串
let arr3 = []
arr3.push(arr[0] / 2)
arr3.push(arr[arr.length - 1] / 2 + 0.5)
arr2.push(arr3)
})
//console.log(arr2)
this.timeStr[i] = timeToStr(arr2)
this.timeSection[i] = arr2
}
},
clear() {
this.rowUnit.forEach((item) => {
item.forEach((item1) => {
item1.class = null
})
})
this.timeContent.forEach((item) => {
item.arr = []
})
this.timeSection.forEach((item) => {
//赋值成空数组[]出问题
item.length = 0
})
//遍历赋值成'',不管用
this.timeStr.length = 0
for (let i = 0; i < 7; i++) {
this.timeStr.push('')
}
//this.initState = true
},
//画框操作
kuangMove() {
if (!this.kuangObj.flag) return
if (this.downEvent) {
let x1 = this.kuangObj.oldLeft
let y1 = this.kuangObj.oldTop
let x2 = event.layerX
let y2 = event.layerY
this.kuangObj.left = (x2 > x1 ? x1 : x2)
this.kuangObj.top = (y2 > y1 ? y1 : y2)
this.kuangObj.width = Math.abs(x2 - x1)
this.kuangObj.height = Math.abs(y2 - y1)
}
},
kuangDown() {
this.kuangObj.flag = true
this.kuangObj.oldLeft = event.layerX
this.kuangObj.oldTop = event.layerY
},
kuangUp() {
this.kuangObj.flag = false
this.clearDragData()
},
kuangLeave() {
this.kuangObj.flag = false
this.clearDragData()
},
clearDragData() {
for (let prop in this.kuangObj) {
this.kuangObj[prop] = 0
}
}
}
}
</script>
<style scoped>
.byted-weektime .calendar {
-webkit-user-select: none;
position: relative;
display: inline-block
}
/*.byted-weektime .calendar .schedule{background:#2F88FF;width:0;height:0;position:fixed;display:none;top:0;left:0;pointer-events:none;-webkit-transition:all 400ms ease;-moz-transition:all 400ms ease;-ms-transition:all 400ms ease;transition:all 400ms ease}*/
.byted-weektime .calendar .calendar-table {
border-collapse: collapse;
border-radius: 4px
}
.byted-weektime .calendar .calendar-table tr .calendar-atom-time:hover {
background: #ccc
}
.byted-weektime .calendar .calendar-table tr .ui-selected {
background: #2F88FF
}
.byted-weektime .calendar .calendar-table tr .ui-selected:hover {
background: #2F88FF
}
.byted-weektime .calendar .calendar-table tr,
.byted-weektime .calendar .calendar-table td,
.byted-weektime .calendar .calendar-table th {
border: 1px solid #ccc;
font-size: 12px;
text-align: center;
min-width: 11px;
line-height: 1.8em;
-webkit-transition: background 200ms ease;
-moz-transition: background 200ms ease;
-ms-transition: background 200ms ease;
transition: background 200ms ease
}
.byted-weektime .calendar .calendar-table tbody tr {
height: 30px
}
.byted-weektime .calendar .calendar-table tbody tr td:first-child {
background: #F8F9FA
}
.byted-weektime .calendar .calendar-table thead th,
.byted-weektime .calendar .calendar-table thead td {
background: #F8F9FA
}
.byted-weektime .calendar .calendar-table .td-table-tip {
line-height: 2.4em;
padding: 0 12px 0 19px;
background: #fff !important
}
.byted-weektime .calendar .calendar-table .td-table-tip .clearfix {
height: 46px;
line-height: 46px
}
.byted-weektime .calendar .calendar-table .td-table-tip .pull-left {
font-size: 14px;
color: #333333
}
.byted-weektime .week-td {
width: 75px;
padding: 20px 0
}
.byted-weektime a {
cursor: pointer;
color: #2F88FF;
font-size: 14px
}
#kuang {
position: absolute;
background-color: blue;
opacity: 0.3;
}
</style>
vue2实现时间拖拽选择器
最新推荐文章于 2024-09-05 09:34:10 发布