CSS 转换后 Android 4 Chrome 遇到触摸事件测试问题

2024-01-03

我在 CSS 转换和触摸事件命中测试的组合方面遇到问题。这仅在 Android 4(稳定版和测试版)上的 Chrome 中为我重现。 iOS Safari 以及带有触摸模拟功能的 Chrome 桌面似乎都运行良好。

我几乎肯定这一定是一个错误,所以我想我主要是在这里寻找解决方法。

问题在于,触摸的命中测试似乎只适用于元素在变换之前的位置,而不适用于最终位置。你可以在我的 jsfiddle 上看到一个例子(仅在 Android 4 Chrome 上):

jsfiddle:http://jsfiddle.net/LfaQq/ http://jsfiddle.net/LfaQq/全屏:http://jsfiddle.net/LfaQq/embedded/result/ http://jsfiddle.net/LfaQq/embedded/result/

如果将蓝色框拖动到屏幕的一半位置并释放,它将弹回顶部。现在,如果您尝试再次从页面上半部分拖动,则不会记录任何触摸。触摸事件甚至不会在元素上触发。但是,如果您尝试触摸元素的底部,则效果很好。然后,您可以尝试将其从底部向上移动,并观察命中测试不再在底部起作用,而是在顶部起作用。

这就是我处理事件的方式:

function handleTouch(e) {

    console.log("handle touch")

    e.preventDefault();

    switch(e.type){
        case 'touchstart':
            console.log("touchstart");
            touchOriginY = e.targetTouches[0].screenY;
            break;
        case 'touchmove':
            console.log("touchmove");
            el.innerHTML = e.targetTouches[0].screenY;
            var p = e.targetTouches[0].screenY - touchOriginY;
            el.style[TRANSFORM] = 'translate3d(0,' + p + 'px' + ',0)';
            break;
        case 'touchcancel':
            console.log("touchcancel");
            // Fall through to touchend
        case 'touchend':
            //console.log("touchend");
            //el.style[TRANSITION] = '.4s ease-out';
            el.style[TRANSFORM] = 'translate3d(0,0,0)';
            break;
    }

}

el.addEventListener('touchstart', handleTouch);
el.addEventListener('touchend', handleTouch);
el.addEventListener('touchmove', handleTouch);
el.addEventListener(TRANSITION_END, function(e) {
    console.log("transition end")
    el.style[TRANSITION] = '';
});

我对 touchmove 中的变换没有任何问题,因为无论如何这些都不是要检测的新触摸。

有什么建议么?


这是 Chrome 中的一个不寻常的错误。

本质上,元素的命中目标是在浏览器传递布局期间记录的。每次设置innerHTML时,浏览器都会重新布局,最后一次完成此操作是在触发touchend事件之前。有几种方法可以解决这个问题:

选项 1:您可以在 body 元素上设置触摸处理程序,并检查触摸事件的目标以查看它是否正在触摸红色块。向 Paul Lewis 推荐一下这种方法。

http://jsfiddle.net/FtfR8/5/ http://jsfiddle.net/FtfR8/5/

var el = document.body;
var redblock = $('.splash-section');

function handleTouch(e) {

    console.log("handle touch")
    if(e.target != redblock) {
        return;
    }

    ....

选项 2:在文档上设置一个空的触摸回调似乎也可以解决问题 - 根据一些链接的错误报告,这会导致在主线程上完成命中测试,这会影响性能,但它可以正确计算命中的目标。

http://jsfiddle.net/LfaQq/2/ http://jsfiddle.net/LfaQq/2/

document.body.addEventListener('touchstart', function(){});

选项 3:在转换结束后设置 innerHTML 以强制重新布局:

el.addEventListener(TRANSITION_END, function(e) {
    console.log("trans end - offsettop:" + el.offsetTop);
    el.style[TRANSITION] = '';
    el.innerHTML = 'Relayout like a boss!';
});

我在这里创建了一个错误报告,Rick Byers 已链接到一个相关错误以及附加信息:

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

CSS 转换后 Android 4 Chrome 遇到触摸事件测试问题 的相关文章

随机推荐