我有一个简单的用户界面,允许桌面浏览器上的用户单击网格中的单元格,然后在按住鼠标按钮的同时,移动鼠标以快速突出显示多个单元格。我通过mousedown
上的mouseover
,mouseup
和document
事件并使用布尔标志来指示是否按住鼠标按钮来完成此操作。在桌面浏览器上可以正常工作。
问题出在移动浏览器上。这些鼠标事件不存在,我知道我们需要使用touch
事件来代替,但是在Google,SO等进行了广泛搜索之后,我找不到一种一致,可行的方式来执行相同的操作移动浏览器。
我所见过的最接近的是从touchstart
开始,然后通过touchmove
和evt.touches[0].clientX/Y
属性跟踪手指的运动。是否有更好/更简单的方法来执行此操作,还是我们被迫使用clientX/Y
基本上检查屏幕坐标,以弄清楚我们正在“悬停”在哪个DOM元素上并相应地突出显示DOM元素?
我认为您正在寻找正确的解决方案。这周我不得不做类似的事情。一条建议是:
onTouchStart
事件触发时,在onTouchMove
上设置document
事件,这样即使用户移出触发初始事件的元素,它也会触发。 (这可能与您的特定用户界面无关)
感谢大家在解决这个问题上的帮助。实际上,document.elementFromPoint
方法是关键,无需大量额外代码即可实现所有操作。
这是一个示例代码,当用户单击鼠标/在屏幕上点击手指并开始在周围移动鼠标/手指时,该代码允许我在台式机和移动设备上寻找网格单元高亮显示:
var isTouchDevice = 'ontouchstart' in document.documentElement;
var isActivelySelecting = false;
var currHoverTarget = null;
if (isTouchDevice) { // Mobile version
document.addEventListener('touchstart', (evt) => {
var target = evt.target;
if (target.classList.contains('class-name-of-selectable-grid-cells')) {
isActivelySelecting = true;
currHoverTarget = target;
toggleSelection(target); // Function for storing selected cells in an array
// For turning off text highlighting as you select cells
document.querySelector('body').classList.add('noHighlighting');
// Stops screen from scrolling on mobile while selecting cells.
evt.preventDefault();
}
}, {
passive: false // Needed to avoid errors in some browsers.
});
document.addEventListener('touchmove', (evt) => {
if (isActivelySelecting) {
var target = evt.target;
if (target.classList.contains('class-name-of-selectable-grid-cells')) {
var x = evt.touches[0].clientX;
var y = evt.touches[0].clientY;
var hoveredElem = document.elementFromPoint(x, y); // The secret sauce
// Only true when going from one DOM element to another.
// Basically simulates the mouseover event for desktop browsers.
if (hoveredElem !== currHoverTarget) {
currHoverTarget = hoveredElem;
toggleSelection(hoveredElem); // Function for storing selected cells in an array
}
}
}
});
document.addEventListener('touchend', () => {
isActivelySelecting = false;
currHoverTarget = false;
document.querySelector('body').classList.remove('noHighlighting');
});
} else { // Desktop version
document.addEventListener('mousedown', (evt) => {
var target = evt.target;
if (target.classList.contains('class-name-of-selectable-grid-cells')) {
isActivelySelecting = true;
toggleSelection(target); // Function for storing selected cells in an array
// For turning off text highlighting as you select cells
document.querySelector('body').classList.add('noHighlighting');
}
});
document.addEventListener('mouseover', (evt) => {
if (isActivelySelecting) {
var target = evt.target;
if (target.classList.contains('class-name-of-selectable-grid-cells')) {
toggleSelection(target); // Function for storing selected cells in an array
}
}
});
document.addEventListener('mouseup', () => {
isActivelySelecting = false;
document.querySelector('body').classList.remove('noHighlighting');
});
}