在尝试了几件事(postMessage,Worker,...)之后总是遇到 IE9 问题,我找到了很好的解决方案。我使用 setInterval 函数制作了 Parallel.For 循环。捕获在这里:
setInterval() 方法将继续调用该函数,直到调用 clearInterval() 或关闭窗口。
创建节点的逻辑在子窗口中,但它是从父窗口触发的。循环是分块执行的,因为使用了 setInterval,所以在任何时候关闭子窗口都不会产生错误。此外,浏览器不会挂起(运行时无论是父母还是孩子)。它看起来像这样:
我们有 3 个组件:parent-ie.html、child-ie.html 和小的 parallel.js 文件。一个怪癖是,所有浏览器都使用了 setInterval(function, -1)。正值是制动 IE,第二个省略的参数使 Opera 感到困惑,因此它只产生了第一个功能块。无论如何,代码在这里:
父id.html
<!DOCTYPE html>
<html>
<head>
<title>Parent</title>
</head>
<body>
<script type="text/javascript">
'use strict';
(function(){
var popup;
var pathname = 'child-ie.html';
window.openPopup = function _open() {
popup = window.open(pathname, 'open', 'width=500,height=300,scrollbars=yes,resizable=yes');
}
window.createElements = function _createElements() {
if (popup == null || popup.closed == true) {
alert("Open new popup window first.");
return;
}
var numberOfElements = parseInt(document.getElementById('numberOfElements').value);
popup.writeElements(numberOfElements);
}
})();
</script>
<button onclick="openPopup()">Open popup</button><br />
<button onclick="createElements()">Create elements</button>
<input id="numberOfElements" type="number" value="10000" />
</body>
</html>
child-ie.html
<!doctype html>
<html>
<head>
<title>Child window</title>
</head>
<body>
<script src="/Scripts/Parallel.js"></script>
<script>
(function(){
function _iterator(index) {
var node = document.createTextNode(index + " ");
document.body.appendChild(node);
}
window.writeElements = function (numberOfElements) {
document.body.innerHTML = '';
Parallel.For(0, numberOfElements, 100, _iterator);
}
})();
</script>
</body>
</html>
/Scripts/Parallel.js
'use strict';
var Parallel;
(function (Parallel) {
var Iterator = (function () {
function Iterator(from, to, step, expression) {
this._from = from;
this._to = to;
this._step = step;
this._expression = expression;
}
Object.defineProperty(Iterator.prototype, "intervalHandle", {
set: function (value) {
this._intervalHandle = value;
},
enumerable: true,
configurable: true
});
Iterator.prototype.next = function () {
var max = this._to > this._step + this._from ? this._step + this._from : this._to;
for(var i = this._from; i < max; i += 1) {
this._expression(i);
}
if(max === this._to) {
clearInterval(this._intervalHandle);
} else {
this._from = max;
}
};
return Iterator;
})();
function For(from, to, step, expression) {
var _iterator = new Iterator(from, to, step, expression);
_iterator.intervalHandle = setInterval(function () {
_iterator.next();
}, -1);
}
Parallel.For = For;
})(Parallel || (Parallel = {}));
Javascript 是从 typescript 文件生成的(可能比 javascript 更清晰):
'use strict';
module Parallel {
class Iterator {
private _from: number;
private _to: number;
private _step: number;
private _expression: (index: number) => {};
private _intervalHandle: number;
public set intervalHandle(value: number) {
this._intervalHandle = value;
}
constructor(from: number, to: number, step: number, expression: (index: number) => {}) {
this._from = from;
this._to = to;
this._step = step;
this._expression = expression;
}
next() {
var max: number = this._to > this._step + this._from ? this._step + this._from : this._to;
for (var i = this._from; i < max; i += 1) {
this._expression(i);
}
if (max === this._to) {
clearInterval(this._intervalHandle);
}
else {
this._from = max;
}
}
}
export function For(from: number, to: number, step: number, expression: (index: number) => {}) {
var _iterator = new Iterator(from, to, step, expression);
_iterator.intervalHandle = setInterval(function () {
_iterator.next();
}, -1);
}
}
就这样。