Javascript 在带有触摸事件的移动浏览器上模拟鼠标悬停的最佳方式是什么?
我有一个简单的UI,允许桌面浏览器上的用户点击网格中的一个单元格,在按住鼠标按钮的同时,移动鼠标以快速高亮显示多个单元格。我通过Javascript 在带有触摸事件的移动浏览器上模拟鼠标悬停的最佳方式是什么?,javascript,touch-event,mobile-browser,touchstart,Javascript,Touch Event,Mobile Browser,Touchstart,我有一个简单的UI,允许桌面浏览器上的用户点击网格中的一个单元格,在按住鼠标按钮的同时,移动鼠标以快速高亮显示多个单元格。我通过文档上的mousedown、mouseover和mouseup事件来实现这一点,并使用布尔标志指示鼠标按钮是否被按下。它在桌面浏览器上运行良好 但问题在于移动浏览器。这些鼠标事件并不存在,我知道我们需要使用touch事件来代替,但是在谷歌搜索了这么多之后,我找不到一个一致的、可行的方法在移动浏览器上做同样的事情 我见过的最近的一个例子是用touchstart捕捉开始,然
文档
上的mousedown
、mouseover
和mouseup
事件来实现这一点,并使用布尔标志指示鼠标按钮是否被按下。它在桌面浏览器上运行良好
但问题在于移动浏览器。这些鼠标事件并不存在,我知道我们需要使用touch
事件来代替,但是在谷歌搜索了这么多之后,我找不到一个一致的、可行的方法在移动浏览器上做同样的事情
我见过的最近的一个例子是用
touchstart
捕捉开始,然后用touchmove
和evt.touchs[0].clientX/Y
属性跟踪手指的运动。是否有更好/更简单的方法来实现这一点,或者我们被迫基本上使用clientX/Y
检查屏幕坐标,以确定我们“悬停在”哪个DOM元素上并相应地高亮显示该DOM元素 我认为你找到了正确的解决方案。本周我不得不做类似的事情。有一条建议是:
当触发
onTouchStart
事件时,在文档上设置onTouchMove
事件,这样即使用户移动到触发初始事件的元素之外,它也会触发。(这可能与您的特定UI无关)我认为您找到了正确的解决方案。本周我不得不做类似的事情。有一条建议是:
当触发onTouchStart
事件时,在文档上设置onTouchMove
事件,这样即使用户移动到触发初始事件的元素之外,它也会触发。(这可能与您的特定UI无关)感谢大家在解决此问题时的帮助。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');
});
}
感谢大家在解决这个问题上的帮助。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');
});
}
谢谢你,杰拉德。是的,我在document
对象上设置了touchmove
,所以我开始了。因此,基本上,对于每个touchmove
,我必须计算我是新悬浮在DOM元素上还是悬浮在现有DOM元素之外,并相应地做我想做的一切?基本上,我们必须为触摸事件手动重新编码mouseover
和mouseout
,是吗?啊!真痛苦,谢谢你,杰拉德。是的,我在document
对象上设置了touchmove
,所以我开始了。因此,基本上,对于每个touchmove
,我必须计算我是新悬浮在DOM元素上还是悬浮在现有DOM元素之外,并相应地做我想做的一切?基本上,我们必须为触摸事件手动重新编码mouseover
和mouseout
,是吗?啊!多痛苦啊。您使用touchstart
、touchmove
和touchend
无疑是正确的,显然有document.elementFromPoint(event.clientX,event.clientY)
,每个文档。elementFromPoint
方法非常方便。这将节省大量时间(希望如此)。谢谢。您使用touchstart
、touchmove
和touchend
无疑是正确的,显然有document.elementFromPoint(event.clientX,event.clientY)
,每个文档。elementFromPoint
方法非常方便。这将节省大量时间(希望如此)。谢谢