在带有触摸事件的移动浏览器中模拟鼠标悬停的最佳方法是什么?

问题描述 投票:1回答:2

我有一个简单的用户界面,允许桌面浏览器上的用户单击网格中的单元格,然后在按住鼠标按钮的同时,移动鼠标以快速突出显示多个单元格。我通过mousedown上的mouseovermouseupdocument事件并使用布尔标志来指示是否按住鼠标按钮来完成此操作。在桌面浏览器上可以正常工作。

问题出在移动浏览器上。这些鼠标事件不存在,我知道我们需要使用touch事件来代替,但是在Google,SO等进行了广泛搜索之后,我找不到一种一致,可行的方式来执行相同的操作移动浏览器。

我所见过的最接近的是从touchstart开始,然后通过touchmoveevt.touches[0].clientX/Y属性跟踪手指的运动。是否有更好/更简单的方法来执行此操作,还是我们被迫使用clientX/Y基本上检查屏幕坐标,以弄清楚我们正在“悬停”在哪个DOM元素上并相应地突出显示DOM元素?

javascript touch-event mobile-browser touchstart
2个回答
0
投票

我认为您正在寻找正确的解决方案。这周我不得不做类似的事情。一条建议是:

onTouchStart事件触发时,在onTouchMove上设置document事件,这样即使用户移出触发初始事件的元素,它也会触发。 (这可能与您的特定用户界面无关)


0
投票

感谢大家在解决这个问题上的帮助。实际上,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');
    });
}
© www.soinside.com 2019 - 2024. All rights reserved.