<template>
<el-dialog
title="时间段选择"
:visible.sync="dialogVisible"
:close-on-click-modal="false"
custom-class="custom-dialog-style"
width="1000px"
:close="close"
>
<div class="container">
<div class="wrap">
<div class="right">
<div class="bottom" @mousedown="handleMouseDown">
<div
:style="
'width:' +
mask_width +
'left:' +
mask_left +
'height:' +
mask_height +
'top:' +
mask_top
"
v-show="positionList.is_show_mask"
class="mask"
></div>
<div v-for="i in 30" class="box">
<div class="check_box">
<i class="el-icon-check"></i>
</div>
<span>*</span>
<div>出函机构</div>
</div>
</div>
</div>
</div>
</div>
<div slot="footer">
<el-button @click="close">取 消</el-button>
<el-button type="primary" @click="submit">确 定</el-button>
</div>
</el-dialog>
</template>
<script>
const positionList = {
is_show_mask: false,
box_screen_left: 0, // 盒子距离浏览器左侧的距离
box_screen_top: 0, //盒子距离浏览器顶部的距离
start_x: 0,
start_y: 0,
end_x: 0,
end_y: 0
};
export default {
data() {
return {
dialogVisible: true,
totalNum: 336,
dataItem: [],
isClick: true,
positionList: { ...positionList }
};
},
computed: {
mask_width() {
return `${Math.abs(
this.positionList.end_x - this.positionList.start_x
)}px;`;
},
mask_height() {
return `${Math.abs(
this.positionList.end_y - this.positionList.start_y
)}px;`;
},
mask_left() {
return `${Math.min(this.positionList.start_x, this.positionList.end_x) -
this.positionList.box_screen_left}px;`;
},
mask_top() {
return `${Math.min(this.positionList.start_y, this.positionList.end_y) -
this.positionList.box_screen_top}px;`;
}
},
mounted() {
this.init();
},
methods: {
init() {
// ref 调用init弹窗即可
this.dialogVisible = true;
this.initList();
},
initList() {
for (let i = 1; i <= this.totalNum; i++) {
let map = {
selected: false,
key: i
};
this.dataItem.push(map);
}
},
setData(value) {
this.initList();
value.forEach(v => {
this.dataItem[v - 1].selected = true;
});
},
handleMouseDown(event) {
this.positionList.is_show_mask = true;
this.positionList.start_x = event.clientX;
this.positionList.start_y = event.clientY;
this.positionList.end_x = event.clientX;
this.positionList.end_y = event.clientY;
this.positionList.box_screen_left = document
.querySelector(".bottom")
.getBoundingClientRect().left;
this.positionList.box_screen_top = document
.querySelector(".bottom")
.getBoundingClientRect().top;
document.body.addEventListener("mousemove", this.handleMouseMove); //监听鼠标移动事件
document.body.addEventListener("mouseup", this.handleMouseUp); //监听鼠标抬起事件
},
handleMouseMove(event) {
this.positionList.end_x = event.clientX;
this.positionList.end_y = event.clientY;
},
handleMouseUp(event) {
document.body.removeEventListener("mousemove", this.handleMouseMove);
document.body.removeEventListener("mouseup", this.handleMouseUp);
// this.positionList = { ...positionList };
// this.positionList.is_show_mask = false;
// this.handleDomSelect();
// this.resSetXY();
},
handleDomSelect() {
const dom_mask = window.document.querySelector(".mask");
// getClientRects()方法 每一个盒子的边界矩形的矩形集合
const rect_select = dom_mask.getClientRects()[0];
document.querySelectorAll(".select-item").forEach((node, index) => {
const rects = node.getClientRects()[0];
if (this.collide(rects, rect_select) === true) {
this.dataItem[index].selected = !this.dataItem[index].selected;
}
});
},
collide(rect1, rect2) {
const maxX = Math.max(rect1.x + rect1.width, rect2.x + rect2.width);
const maxY = Math.max(rect1.y + rect1.height, rect2.y + rect2.height);
const minX = Math.min(rect1.x, rect2.x);
const minY = Math.min(rect1.y, rect2.y);
return (
maxX - minX <= rect1.width + rect2.width &&
maxY - minY <= rect1.height + rect2.height
);
},
resSetXY() {
this.positionList.start_x = 0;
this.positionList.start_y = 0;
this.positionList.end_x = 0;
this.positionList.end_y = 0;
},
close() {
this.dialogVisible = false;
this.dataItem = [];
},
submit() {}
}
};
</script>
<style lang="scss" scoped>
.container {
height: 600px;
border: 1px solid #f1f1f1;
.box {
display: flex;
-moz-user-select: none; /* Firefox私有属性 */
-webkit-user-select: none; /* WebKit内核私有属性 */
-ms-user-select: none; /* IE私有属性(IE10及以后) */
-khtml-user-select: none; /* KHTML内核私有属性 */
-o-user-select: none; /* Opera私有属性 */
user-select: none; /* CSS3属性 */
cursor: pointer;
span {
color: red;
margin: 3px;
}
min-width: 120px;
line-height: 20px;
height: 20px;
padding: 30px;
}
.check_box {
width: 16px;
height: 16px;
border: 1px solid #f1f1f1;
margin-top: 3px;
}
.wrap {
display: flex;
border: 1px solid #f1f1f1;
border-bottom: 0;
flex-wrap: wrap;
.left {
.merge-column {
width: 4vw;
height: 6vh;
padding: 3px 5px;
min-width: 76px;
min-height: 55px;
display: flex;
align-items: center;
border-right: 1px solid #f1f1f1;
border-bottom: 1px solid #f1f1f1;
}
.td-title {
width: 4vw;
height: 3vh;
min-height: 27px;
min-width: 76px;
padding: 3px 5px;
text-align: center;
border-right: 1px solid #f1f1f1;
border-bottom: 1px solid #f1f1f1;
}
&:last-child {
border-bottom: 0;
}
}
.right {
display: flex;
flex-wrap: wrap;
.top {
width: 100%;
display: flex;
flex-wrap: wrap;
align-content: flex-start;
.merge-row {
width: 50%;
height: 3vh;
padding: 3px 5px;
min-width: 420px;
min-height: 27px;
text-align: center;
border-right: 1px solid #f1f1f1;
border-bottom: 1px solid #f1f1f1;
&:nth-child(2) {
border-right: 0;
}
}
.unit {
width: calc(100% / 24);
height: 3vh;
padding: 3px 5px;
min-width: 35px;
min-height: 27px;
text-align: center;
border-right: 1px solid #f1f1f1;
border-bottom: 1px solid #f1f1f1;
&:last-child {
border-right: 0;
}
}
}
.bottom {
width: 100%;
position: relative;
display: flex;
flex-wrap: wrap;
.mask {
position: absolute;
background: #409eff;
opacity: 0.4;
z-index: 100;
left: 0;
top: 0;
}
.select-item {
width: calc(100% / 48);
height: 3vh;
min-width: 17px;
min-height: 27px;
cursor: pointer;
padding: 3px 5px;
border-right: 1px solid #f1f1f1;
border-bottom: 1px solid #f1f1f1;
&:hover {
background: #f1f1f1;
}
}
.selected {
background: #7bc8ff;
&:hover {
background: #7bc8ff;
}
}
*:nth-child(48n + 1) {
border-right: 0;
}
}
}
}
}
</style>