使用说明:
1、长按可拖拽移动座位
2、右击座位可删除座位和修改座位号
3、右击图纸空白处可添加座位
注意:为了避免拖拽事件与左击事件冲突,所以采用右击模式,使用的vue语法
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<!-- 1.引入-->
<script src="./vue.js"></script>
<style>
#seat_app {
position: relative;
width: 1000px;
}
.seatBox {
width: 1000px;
min-height: 800px;
/* height: 100%; */
background: transparent;
top: 0;
position: absolute;
border: 1px solid #f00;
}
.seatNumber {
min-width: 30px;
height: 30px;
line-height: 30px;
background-color: #35A714;
/* border: 1px solid #f00; */
display: inline-block;
color: #333;
font-size: 20px;
text-align: center;
cursor: pointer;
position: absolute;
color: #fff;
}
.seatNumber span {
display: inline-block;
position: absolute;
width: 5px;
height: 2px;
background-color: #fff;
}
.seatNumber span:nth-child(1) {
top: 0;
left: 0;
}
.seatNumber span:nth-child(2) {
top: 0;
right: 0;
}
.seatNumber span:nth-child(3) {
left: 0;
bottom: 0;
}
.seatNumber span:nth-child(4) {
bottom: 0;
right: 0;
}
#seat_menu {
width: 200px;
/* height: 300px; */
background: rgb(64, 164, 226);
display: none;
position: absolute;
z-index: 8;
color: #fff;
}
#seat_menu li {
width: 80%;
margin: 15px 0;
cursor: pointer;
border-bottom: 1px solid transparent;
}
#seat_menu li:hover {
border-color: #fff;
}
#seatBg {
position: absolute;
top: 0;
width: 100%;
}
.seat_bindinged {
width: 360px;
border: 2px solid #D30000;
background-color: #fff;
position: absolute;
top: 40px;
left: -180px;
font-size: 14px;
display: none;
}
.seat_bindinged p {
padding: 0;
font-size: 16px;
margin: 0;
height: 40px;
line-height: 40px;
background-color: #D30000;
color: #fff;
text-align: center;
}
.seat_bindinged li {
height: 30px;
line-height: 30px;
color: #333;
}
.seat_bindinged li i {
float: right;
}
.seat_check,
.seat_lock,
.seat_reserve {
position: absolute;
display: none;
color: #333;
}
.seatNumber:hover .seat_check,
.seatNumber:hover .seat_lock,
.seatNumber:hover .seat_bindinged,
.seatNumber:hover .seat_reserve {
/* display: block; */
}
#seat_del {
width: 150px;
display: inline-block;
background-color: rgb(202, 4, 4);
min-height: 40px;
line-height: 40px;
color: #fff;
cursor: pointer;
display: none;
position: absolute;
z-index: 8;
}
#seat_del span {
display: inline-block;
border-bottom: 1px solid transparent;
height: 35px;
width: 80%;
text-align: center;
margin-left: 10%;
}
#seat_del p:hover span {
border-color: #fff;
}
</style>
</head>
<body>
<p>使用说明: </p>
<p> 1、长按可拖拽移动座位</p>
<p>2、右击座位可删除座位和修改座位号</p>
<p>3、右击图纸空白处可添加座位</p>
<p>由于拖拽事件与左击事件冲突,所以采用右击模式</p>
<!-- 作用域 -->
<div id="seat_app">
<img id="seatBg" src="./bg.png" alt="">
<ul class="seatBox">
<li v-for="item in seatlist" class="seatNumber"
:style=`top:${item.y}px;left:${item.x}px;background-color:${item.color};`>
<span></span><span></span><span></span><span></span>
{{item.num}}
<!-- 鼠标经过座位的样式 1 -->
<div class="seat_reserve" v-if="item.status==1">
可预订
</div>
<!-- 鼠标经过座位的样式 2-->
<div class="seat_check" v-if="item.status==2">
审核中
</div>
<!-- 鼠标经过座位的样式 3 -->
<div class="seat_bindinged" v-if="item.status==3">
<p>展位状态:已预订</p>
<ul>
<li>{{item.firmName}}</li>
<li v-for="i in item.joblist">职位:{{i.jobname}} <i>人数:{{i.people}}人</i></li>
</ul>
</div>
<!-- 鼠标经过座位的样式 4 -->
<div class="seat_lock" v-if="item.status==4">
已锁定
</div>
</li>
<!-- <li class="seatNumber"><span></span><span></span><span></span><span></span>1</li> -->
</ul>
<div id="seat_menu">
<ol>
<li @click="addSeat">添加座位</li>
<!-- <li @click="changeIndex"></li> -->
</ol>
</div>
<div id="seat_del">
<p @click="removeSeat"><span>1、删除座位</span> </p>
<p @click="changeIndex"><span>2、修改座位号</span></p>
</div>
</div>
<script>
// 拖拽方法
var drag = function (ele) {
var l = undefined
var t = undefined
ele.onmousedown = function (e) {
e = e || window.event;
// 计算误差(鼠标按下瞬间,鼠标距离box元素的距离)
var deltaX = e.clientX - ele.offsetLeft;
var deltaY = e.clientY - ele.offsetTop;
document.onmousemove = function (e) {
e = e || window.event;
// 获取鼠标的位置,减去误差,再赋值
l = e.clientX - deltaX;
t = e.clientY - deltaY;
// 验收,在屏幕可视区内拖拽
if (l < 0) l = 0;
if (t < 0) t = 0;
if (l > document.documentElement.clientWidth - ele.offsetWidth) l = document.documentElement.clientWidth - ele.offsetWidth;
if (t > document.documentElement.clientHeight - ele.offsetHeight) t = document.documentElement.clientHeight - ele.offsetHeight;
ele.style.left = l + 'px';
ele.style.top = t + 'px';
}
// 取消默认行为
return false;
}
ele.onmouseup = function () {
// console.log("鼠标抬起事件");
console.log("数据:x=" + l, "y=" + t);
}
// 鼠标抬起,取消移动事件
document.onmouseup = function () {
document.onmousemove = null;
}
}
// 3.实例化vue
new Vue({
el: '#seat_app',
data: {
seatlist: [
{ x: 153, y: 153, num: 1, status: 1, color: "#35A714;" },
{ x: 212, y: 153, num: 2, status: 2, color: "#FC9F01;" },
{
x: 278,
y: 153,
num: 3,
status: 3,
color: "#D30000;",
firmName: "甘肃省某某某某某某111公司",
joblist: [
{ jobname: "自动化工程师", people: "10" },
{ jobname: "PAD板绘制工程师", people: "5" },
],
},
{ x: 338, y: 153, num: 4, status: 4, color: "#424242;" },
{ x: 397, y: 153, num: 5, status: 1, color: "#35A714;" },
{ x: 458, y: 153, num: 6, status: 1, color: "#35A714;" },
{ x: 520, y: 153, num: 7, status: 1, color: "#35A714;" },
{ x: 580, y: 153, num: 8, status: 1, color: "#35A714;" },
{ x: 642, y: 153, num: 9, status: 2, color: "#FC9F01;" },
{ x: 702, y: 153, num: 10, status: 3, color: "#D30000;" },
{ x: 762, y: 153, num: 11, status: 4, color: "#424242;" },
],
seatBox: undefined,
l: null,//鼠标右击的位置
t: null,//鼠标右击的位置
delNumDom: null,//要删除的节点
},
mounted() {
this.$nextTick(() => {
this.seatBox = document.querySelector(".seatBox")
let dom = document.querySelectorAll(".seatNumber")
if (dom) {
dom.forEach(item => {
// console.log(item.textContent, "座位号");
drag(item);
})
}
var seat_menu = document.getElementById('seat_menu');
var seatDel = document.getElementById('seat_del');
$this = this;
// ***********************自定义鼠标右击事件*****************************
this.seatBox.oncontextmenu = function (e) {
e = e || window.event;
var target = e.target || e.srcElement;//事件委托
// 取得鼠标位置
let l = e.clientX;
let t = e.clientY;
console.log(l,t,e);
// 右击座位
if (target.className == 'seatNumber') {
console.log(target, seatDel, "子集");
seatDel.style.display = 'block';
seatDel.style.left = l + 'px';
seatDel.style.top = t + 5 + 'px';
$this.delNumDom = target
} else {//右击座位以外的其他地方
seat_menu.style.display = 'block';
seat_menu.style.left = l + 'px';
seat_menu.style.top = t + 'px';
}
$this.l = l
$this.t = t
return false
}
document.onclick = function () {
seat_menu.style.display = 'none';
seatDel.style.display = 'none';
}
})
},
methods: {
addSeat() {
this.doingSeat()
},
removeSeat() {
this.delNumDom.remove()
},
// 替换
changeIndex() {
this.delNumDom.remove()
let num = prompt("输入座位号")
this.doingSeat(num)
},
doingSeat(num) {
let li = document.createElement("li");
li.className = "seatNumber";
let length = num ? num : document.querySelectorAll(".seatNumber").length + 1;
// 为了能让座位添加的时候能在右击位置的中心点,所以对top和left进行适当的加减
console.log(this.l,this.t,"鼠标位置");
li.style.top = `${this.t - 40}px`;
li.style.left = `${this.l - 25}px`;
var msg = `<span></span><span></span><span></span><span></span>${length}`
li.innerHTML = msg
this.seatBox.appendChild(li);
// 给新增的节点添加拖拽事件
let dom = document.querySelectorAll(".seatNumber")
if (dom) {
dom.forEach(item => {
drag(item);
})
}
}
}
})
</script>
</body>
</html>