Microsoft Edge:与print()

时间:2016-12-14 22:30:56

标签: javascript printing setinterval microsoft-edge

我发现了Microsoft Edge中的一个错误。执行print()时有时会调用setInterval()的回调。这导致2个JavaScript函数并行运行,不应该被允许,对吧?

使用这个简单的测试应用程序可以观察到这种行为。

的index.html:

<!DOCTYPE html>
<html>    
  <head>
    <script src="script.js"></script>
  </head>
  <body>
    <input type="button" onclick="printPage()" value="Print"/>
  </body>
</html>

的script.js:

var isPrinting = false;

setInterval(function tick() {
  if (isPrinting) {
    alert('Interval callback called conurrently with click handler!');
  }  
}, 10);

function printPage() {
  isPrinting = true;
  try {
    print();
  }
  finally {
    isPrinting = false;
  }
}

https://plnkr.co/edit/eKMQEHjRiXzl1vzjzIEN

当我点击“打印”按钮时,我不希望看到警报,但我确实发现了警报。

环境:Microsoft Edge 38.14393.0.0,Windows 10

这是一个错误还是我不明白?

2 个答案:

答案 0 :(得分:0)

是的,这是一个确认的错误。我有点惊讶,没有人在我面前有这样的报道。

https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/10230373/

答案 1 :(得分:0)

以下是我如何处理这个错误。

(function () {
    var isPrinting = false;
    var _setInterval = window.setInterval;
    var _print = window.print;
    var queue = [];

    window.setInterval = function (fn, delay) {
        var params;
        if (arguments.length > 2) {
            params = arguments.slice(2);
        }
        var wrapper = function () {
            if (!isPrinting) {
                fn.apply(null, params);
            }
            else {
                //console.log('queuing...');
                // Queue only one callback per setInterval() call. This mimics Chrome and IE11's behavior.
                if (!wrapper.queued) {
                    wrapper.queued = true;
                    queue.push(wrapper);
                }
            }
        };
        _setInterval(wrapper, delay);
    };

    window.print = function () {
        //console.log('print begin');
        isPrinting = true;
        try {
            _print.apply(this, arguments);
        }
        finally {
            //console.log('print end');
            isPrinting = false;
            if (queue.length > 0) {
                var _queue = queue; // Save the contents of the queue so that we have them when the timeout callback executes.
                setTimeout(function () {
                    _queue.forEach(function (wrapper) {
                        wrapper.queued = false;
                        wrapper();
                    });
                });
                queue = [];
            }
        }
    }
})();