javascript - 如何防止 IE11 和 Microsoft Edge 积极限制事件?

标签 javascript microsoft-edge

背景

我有一个可平移的应用程序窗口,它通过监听 mousemove 事件然后使用 transform: translate3d(...) 相应地移动屏幕来工作。这是一个大型应用程序,并且有大量相关的 UI 工作来促进此功能。 MCVE 来了,其中真实的工作负载由一个虚拟的 for 循环模拟:

var container = document.getElementById("container");
var contents = document.getElementById("contents");
var input = document.getElementById("iterations");

var posX = 50;
var posY = 50;
var previousX = null;
var previousY = null;

var mousedownHandler = function (e) {
    window.onmousemove = globalMousemoveHandler;
    window.onmouseup = globalMouseupHandler;
    previousX = e.clientX;
    previousY = e.clientY;
}

var globalMousemoveHandler = function (e) {
    var now = Date.now();
    for (var i = 0, n = parseInt(input.value); i < n; i++);
    var elapsed = Date.now() - now;

    posX += e.clientX - previousX;
    posY += e.clientY - previousY;
    previousX = e.clientX;
    previousY = e.clientY;
    contents.style.transform = "translate3d(" + posX + "px, " + posY + "px, 0)";
    contents.innerText = elapsed + "ms";
}

var globalMouseupHandler = function (e) {
    window.onmousemove = null;
    window.onmouseup = null;
    previousX = null;
    previousY = null;
}

container.onmousedown = mousedownHandler;
contents.style.transform = "translate3d(" + posX + "px, " + posY + "px, 0)";
#container {
  height: 180px;
  width: 600px;
  background-color: #ccc;
  overflow: hidden;
  cursor: -webkit-grab;
  cursor: -moz-grab;
  cursor: grab;
  -moz-user-select: none;
  -ms-user-select: none;
  -webkit-user-select: none;
  user-select: none;
}

#container:active {
  cursor: move;
  cursor: -webkit-grabbing;
  cursor: -moz-grabbing;
  cursor: grabbing;
}
<label>Iterations: <input id="iterations" type="number" value="20000000" step="5000000" /></label>

<div id="container">
    <div id="contents">
        Pannable container contents...
    </div>
</div>

JSFiddle example with larger drag-area

请按住并拖动示例。

每次 mousemove 触发时,这个基本片段都会运行一个虚拟的 for 循环,并且循环完成所需的持续时间会显示在可拖动容器中。这需要证明下面的问题。您可能需要调整迭代次数,使循环运行时间超过 10 毫秒,但不会太长。

问题

此代码段在 Google Chrome 中运行得尽可能快,没有问题。未经 Firefox 测试。

但是,在 Microsoft Edge (可能还有 IE11) 如果 globalMousemoveHandler 运行时间超过 10 毫秒,浏览器就会开始无情地限制事件,使其触发频率要低得多,并且将平移进度变成爬行。

同样很奇怪的是,for 循环实际上在 Microsoft Edge 中比在 Chrome 中运行更快(快了将近 50%),但事件仍然触发很多 不太频繁。

从上述浏览器查看时,可以在上面的代码片段中观察到这一点。现在我明白了这个功能背后的理论需求,但它使我的应用程序在这些浏览器上不可用——我也不太明白在 16 毫秒以下开始节流有什么意义 (我远远低于 60 FPS 的帧预算),但这不是现在的问题(尽管我很高兴听到有关此的一些细节)

我怎样才能防止这种情况发生?

最佳答案

这是一个使用 requestAnimationFrame 的例子.

var container = document.getElementById("container");
var contents = document.getElementById("contents");
var input = document.getElementById("iterations");

var posX = 50;
var posY = 50;
var previousX = null;
var previousY = null;

var mousedownHandler = function (e) {
    window.onmousemove = globalMousemoveHandler;
    window.onmouseup = globalMouseupHandler;
    previousX = e.clientX;
    previousY = e.clientY;
}

var globalMousemoveHandler = function (e) {
    posX += e.clientX - previousX;
    posY += e.clientY - previousY;
    previousX = e.clientX;
    previousY = e.clientY;
  
    window.requestAnimationFrame(function () {        
      var now = Date.now();
      for (var i = 0, n = parseInt(input.value); i < n; i++);
      var elapsed = Date.now() - now;

      contents.style.transform = "translate3d(" + posX + "px, " + posY + "px, 0)";
      contents.innerText = elapsed + "ms";
    });
}

var globalMouseupHandler = function (e) {
    window.onmousemove = null;
    window.onmouseup = null;
    previousX = null;
    previousY = null;
}

container.onmousedown = mousedownHandler;
contents.style.transform = "translate3d(" + posX + "px, " + posY + "px, 0)";
#container {
  height: 180px;
  width: 600px;
  background-color: #ccc;
  overflow: hidden;
  cursor: -webkit-grab;
  cursor: -moz-grab;
  cursor: grab;
  -moz-user-select: none;
  -ms-user-select: none;
  -webkit-user-select: none;
  user-select: none;
}

#container:active {
  cursor: move;
  cursor: -webkit-grabbing;
  cursor: -moz-grabbing;
  cursor: grabbing;
}
<label>Iterations: <input id="iterations" type="number" value="20000000" step="5000000" /></label>

<div id="container">
    <div id="contents">
        Pannable container contents...
    </div>
</div>

这会阻止处理程序函数的繁重工作,有效地防止问题发生,但代价是延迟增加 16 毫秒。

关于javascript - 如何防止 IE11 和 Microsoft Edge 积极限制事件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40265157/

相关文章:

javascript - 对象传播运算符在 Microsoft Edge 中抛出错误

microsoft-edge - 如何在Windows应用商店中发布Edge扩展?

javascript - 如何从 pdf.js 中的用户选择中检索文本?

javascript - 使用 Phonegap : InvalidCastException 上传图片

javascript - 如何仅使用客户端 JavaScript 正确签署对亚马逊 ItemLookup 的 GET 请求?

javascript - 如何将浏览器控制台日志保存到我的数据库而不覆盖 console.log

windows - MS Edge (Windows 10) 不接受自签名证书

html - Windows 移动 10 : white text in option tags are invisible

javascript - Fetch API 不适用于 Microsoft Edge 中的非英文字符

javascript - jQuery:取消选择元素中的选项