下面的代码实现了将圆点判断移入某个单元格,有优化空间,先放着吧,后面优化细节的时候再改
<template>
<view id="content">
<view id="operatingArea">
<view class="leftbox">
<!-- 数据 -->
data:<br>
<view v-for="(item,index) in record">
{{index}}:
<view style="color: red;" v-for="(item,index) in record[index]" :key="index">
{{item.id}}
</view>
</view>
</view>
<view :prop="record" :change:prop="squareBox.updateData" class="content">
<view class="rows" row="1">
<view id="item1-1" class="areaitem" location="1-1"></view>
<view id="item1-2" class="areaitem" location="1-2"></view>
<view id="item1-3" class="areaitem" location="1-3"></view>
</view>
<view class="rows" row="2">
<view id="item2-1" class="areaitem" location="2-1"></view>
<view id="item2-2" class="areaitem" location="2-2"></view>
<view id="item2-3" class="areaitem" location="2-3"></view>
</view>
<view class="rows" row="3">
<view id="item3-1" class="areaitem" location="3-1"></view>
<view id="item3-2" class="areaitem" location="3-2"></view>
<view id="item3-3" class="areaitem" location="3-3"></view>
</view>
</view>
<view class="rightbox">
</view>
</view>
</view>
</template>
<script>
export default {
data() {
return {
record: {
'item1-1': [],
'item1-2': [],
'item1-3': [],
'item2-1': [],
'item2-2': [],
'item2-3': [],
'item3-1': [],
'item3-2': [],
'item3-3': [],
},
num: 1
};
},
mounted() {},
methods: {
updataServiceData(newdata) {
this.record = JSON.parse(newdata)
// console.log(newdata)
}
}
}
</script>
<script module="squareBox" lang="renderjs">
import {
pointer
} from "../../static/point.js"
let squareBox
export default {
data() {
return {
lastel: null,
drag: false
}
},
mounted() {
pointer.init()
this.Initialization()
const parent = document.querySelector('#content')
parent.addEventListener('touchend', (e) => {
let allArea = document.querySelectorAll('.areaitem')
allArea.forEach(area => {
area.style.backgroundColor = '#fff'
})
})
},
methods: {
updateData(newValue, oldValue, ownerInstance, instance) {
ownerInstance.callMethod('updataServiceData', JSON.stringify(this.record)) //更新数据到seriver层
},
generateRandomID() {
var characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
var id = '';
for (var i = 0; i < 6; i++) {
var randomIndex = Math.floor(Math.random() * characters.length);
id += characters.charAt(randomIndex);
}
return 'c' + id;
},
Initialization() {
Object.keys(this.record).forEach(key => {
let random_number = Math.floor(Math.random() * 10) + 1;
let data = []
for (let i = 0; i < random_number; i++) {
data.push({
id: this.generateRandomID(),
propertys: {
num: 1,
name: '罐名字'
}
})
}
this.record[key] = [...data]
})
this.createCircle()
},
createCircle() { //生成圆圈函数
Object.keys(this.record).forEach(item => {
let area = document.querySelector('#' + item)
this.handleAreaEvent(area)
this.record[item].forEach((el, i) => {
let circle = document.createElement("div");
circle.id = el.id;
circle.innerHTML = "c" + i + 1;
circle.classList.add('circleinside', 'circleitem')
circle.setAttribute("property", JSON.stringify(el.propertys));
this.handleEvent(circle)
area.appendChild(circle)
})
})
},
updateRecord(currentCircleId) { //更新数据
let currentCircleData
Object.keys(this.record).forEach(key => {
this.record[key].forEach(circle => {
if (circle.id === currentCircleId) {
currentCircleData = circle
this.record[key].splice(this.record[key].indexOf(circle), 1)
}
})
})
this.record[this.lastel.id].push(currentCircleData)
},
cancelEvent(type) {
let allcircle = document.querySelectorAll('.circleitem')
if (type) {
allcircle.forEach(circle => {
circle.style.pointerEvents = 'none'
})
} else {
allcircle.forEach(circle => {
circle.style.pointerEvents = 'auto'
})
}
},
handleEvent(el) { //圆圈事件
let clickTimeout = null;
let currentCircle = null
el.addEventListener('click', (e) => {
clearTimeout(clickTimeout);
alert(e.target.id + '\n' + JSON.parse(e.target.getAttribute('property')).name)
})
let touchstart = (e) => {
this.drag = true
// currentCircle.style.pointerEvents = 'none'
currentCircle = e.target
currentCircle.style.background = 'green'
this.cancelEvent(true)
currentCircle.addEventListener('touchmove', touchmove)
}
let touchmove = (e) => {
let touch = e.touches[0];
currentCircle.style.position = 'absolute'
currentCircle.style.left = touch.clientX - 20 + 'px'
currentCircle.style.top = touch.clientY - 20 + 'px'
el.addEventListener('touchend', touchend)
document.querySelector('#content').appendChild(currentCircle)
}
let touchend = (e) => {
currentCircle.style.position = 'static'
currentCircle.style.background = 'red'
this.drag = false
this.lastel.appendChild(currentCircle)
this.updateRecord(currentCircle.id)
clearTimeout(clickTimeout);
this.cancelEvent(false)
console.log('end')
}
el.addEventListener('touchstart', (e) => {
clearTimeout(clickTimeout);
clickTimeout = setTimeout(() => {
touchstart(e)
}, 90);
})
},
// 九宫格事件
handleAreaEvent(el) {
pointer.onEnter(el, el => {
if (!this.drag) return
el.style.backgroundColor = 'rgba(0,0,0,.1)'
this.lastel = el
})
pointer.onLeave(el, el => {
if (!this.drag) return
// this.lastel =
el.style.backgroundColor = '#fff'
})
}
},
};
</script>
<style lang="less">
#content {
display: flex;
height: 100vh;
overflow: hidden;
position: relative;
}
.circleitem {
z-index: 100;
border-radius: 50%;
background-color: red;
border: 1rpx solid black;
display: flex;
justify-content: center;
align-items: center;
line-height: 50rpx;
}
#operatingArea {
flex: 1;
background-color: #efcfff;
display: flex;
// flex-direction: column;
.leftbox,
.rightbox {
width: 20%;
overflow-y: auto;
}
.content {
flex: 1;
display: flex;
flex-direction: column;
.rows {
flex: 1;
width: 100%;
height: 40rpx;
display: flex;
.areaitem {
flex: 1;
border: 1rpx solid #000;
background-color: #fff;
overflow-y: auto;
padding-right: 10%;
box-sizing: border-box;
.circleinside {
position: static;
display: inline-block !important;
margin: 10rpx;
text-align: center;
line-height: 50rpx;
}
}
}
}
}
</style>
实现touch的移入移出
/**
* Simulate touchenter and touchleave by tracking touchmove. See https://stackoverflow.com/questions/23111671/touchenter-and-touchleave-events-support
*/
const touchEventSimulator = {
// enterElementCallback stores element as key and callback as value
enterElementCallback: new Map(),
leaveElementCallback: new Map(),
previousElement: null,
init: function() {
window.addEventListener('touchmove', event => {
var currentElement = document.elementFromPoint(event.touches[0].clientX, event.touches[0]
.clientY)
if (currentElement !== this.previousElement) {
// touch leave
const leaveCallback = this.leaveElementCallback.get(this.previousElement)
if (leaveCallback) {
leaveCallback.call(null, this.previousElement)
}
// touch enter
const enterCallback = this.enterElementCallback.get(currentElement)
if (enterCallback) {
enterCallback.call(null, currentElement)
}
// Current element will be the previous one, next time we check.
this.previousElement = currentElement;
}
});
window.addEventListener('touchend', event => {
this.previousElement = null
})
},
onEnter(element, callback) {
this.enterElementCallback.set(element, callback);
},
onLeave(element, callback) {
this.leaveElementCallback.set(element, callback);
}
}
const mouseAvailable = matchMedia('(pointer:fine)').matches;
export const pointer = {
mouseAvailable,
init() {
if (!mouseAvailable) {
touchEventSimulator.init()
}
},
onEnter: (element, callback) => {
if (mouseAvailable) {
element.addEventListener('mouseenter', () => callback.call(null, element))
} else {
touchEventSimulator.onEnter(element, callback)
}
},
onLeave: (element, callback) => {
if (mouseAvailable) {
element.addEventListener('mouseleave', () => callback.call(null, element))
} else {
touchEventSimulator.onLeave(element, callback)
}
}
}