在uniapp中使用浏览器原生方法,dom操作等

377 阅读1分钟

下面的代码实现了将圆点判断移入某个单元格,有优化空间,先放着吧,后面优化细节的时候再改


<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)
		}
	}
}