为什么在触发 touchstart 事件时 setTimeout 游戏循环会出现延迟?

Fra*_*ank 1 javascript debugging android google-chrome game-loop

这是我遇到的一个相当具体的问题。该故障似乎只出现在最新的 Android 版 Chrome 更新中,因此规格如下:

应用版本:Chrome 45.0.2454.84

操作系统:安卓4.4.4;XT1031 内部版本/KXB21.14-L2.4

我使用的是 Moto G,但故障也发生在运行相同版本 Chrome 的三星上。无论如何,问题显然是touchstart事件中断了我的window.setTimeout游戏循环。这是代码:

(
    function rafTouchGlitch() {
        /////////////////
        /* FUNCTIONS. */
        ///////////////

        function touchStartWindow(event_) {
            event_.preventDefault();
        }

        ///////////////////////
        /* OBJECT LITERALS. */
        /////////////////////

        var engine = {
            /* FUNCTIONS. */
            start : function(interval_) {
                var handle = this;

                (function update() {
                    handle.timeout = window.setTimeout(update, interval_);

                    /* Draw the background and the red square. */
                    display.fillStyle = "#303030";
                    display.fillRect(0, 0, display.canvas.width, display.canvas.height);

                    display.fillStyle = "#f00000";
                    display.fillRect(red_square.x, red_square.y, 20, 20);

                    /* Update the square's position. */
                    red_square.x++;

                    if (red_square.x > display.canvas.width) {
                        red_square.x = -20;
                    }
                })();
            },
            /* VARIABLES. */
            timeout : undefined
        };

        red_square = {
            /* VARIABLES. */
            x : 0,
            y : 0
        };

        /////////////////
        /* VARIABLES. */
        ///////////////

        var display = document.getElementById("canvas").getContext("2d");

        //////////////////
        /* INITIALIZE. */
        ////////////////

        window.addEventListener("touchstart", touchStartWindow);

        engine.start(1000 / 60);
    })();
Run Code Online (Sandbox Code Playgroud)

这段代码在任何其他浏览器中都能正常工作,甚至在以前版本的 Chrome 中也能正常工作。它在上一个版本中运行良好,但由于某种原因,现在出现了问题。我不确定这是否是 Chrome 端的错误,或者他们是否正在做一些新的事情,而我是那个没有涵盖我的基础的人,但事实仍然是,当touchstart事件发生时,我的游戏循环中存在明显的滞后。

这是一个小提琴:https : //jsfiddle.net/dhjsqqxn/

点击屏幕,看看红色方块是如何滞后的!这很荒谬。您基本上可以通过足够快地点击屏幕来冻结 Timeout 对象。

如果您有 Android 手机,我强烈建议您更新 Chrome 并访问链接以了解我的意思。如果这是一个错误,那就是一个巨大的错误,考虑到移动设备的价值setTimeout和重要性touchstart。如果这不是错误,我真的很想知道我做错了什么。

谢谢你的时间!

Sem*_*mra 5

https://bugs.chromium.org/p/chromium/issues/detail?id=567800

Android Chrome 在 touchmove 期间不会运行预定的 (setTimeout/setInterval) 回调。

作为一种解决方法,您可以尝试 window.requestAnimationFrame() 或在需要保留/检查上次运行时间的 touchmove 事件中手动运行回调。