移动端的touchenter和touchleave事件

419 阅读1分钟

开发移动端的时候发现元素是没有这两个事件的,之前有过提案,被否掉了,但是这跟在一些场景中有很常见,于是找了很久,在stackoverflow有这样一个实现

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;

/**
 * Pointer is a wrapper for mouse and (simulated) touch events
 */
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)
		}
	}
}

在使用的时候直接import引入import { pointer } from ""。

语法大概是这样pointer.event(element, element => {})