我试图了解 iframe 中代码执行顺序的行为,它在 FF 和 chrome 中似乎有所不同。用例很简单:我们在顶层框架中有两个函数,创建管理器和窗口创建。窗口创建函数找到一个 iframe 并将其 src 属性设置为
javascript:top.writeBody(document)'
writeBody 使用 document.write 在框架中插入 html 的位置。插入到其末尾的 html 包含一个带有简单日志语句的脚本标记。创建管理器功能用于跟踪执行顺序,并揭示 FF/IE 与 Chrome 相比在处理顺序方面的差异:
FF中的执行流程是这样的:
[20:40:37.893] Entering creation manager
[20:40:37.893] Starting next job
[20:40:37.893] Invoking createWindow
[20:40:37.894] Setting src of frame
[20:40:37.895] Done setting src on frame
[20:40:37.895] Exiting jobs
[20:40:37.953] >>> executing script in frame
在 chrome 中,相同的代码给出:
Entering creation manager
Starting next job
Invoking createWindow
Setting src of frame
>>> executing script in frame
Done setting src on frame
Exiting jobs
基本上在 chrome 中,iframe 中的脚本在创建管理器调用的堆栈中执行,而在 FF/IE 中,它在创建管理器调用完成后执行。
所以我的问题是:为什么会有所不同,有没有办法让 Chrome 在这种情况下表现得像 FF 和 IE。我有一个庞大的遗留代码库,它依赖于 FF/IE 行为,用例并不像示例那么简单,而是更像意大利面条,所以它真的很有用!
代码示例如下。
<!DOCTYPE html>
<html>
<head>
<title>Test scenario.</title>
<script src="main.js"></script>
</head>
<body>
<script>document.write("<iframe id='c1' src='about:blank'></iframe><iframe id='c2'></iframe>");</script>
</body>
</html>
和 javascript
var jobs = [];
var jobn = 0;
var creationManaer = function() {
console.log('Entering creation manager');
if (jobs.length == 0) {
return;
}
console.log('Starting next job');
jobs[jobn]();
console.log('Exiting jobs');
jobn++;
if (jobn >= jobs.length) {
jobs.length = 0;
jobn = 0;
}
}
var body = "<script>" +
"console.log(' >>> executing script in frame');" +
"</script>" +
"<body></body>";
var writeBody = function(doc) {
doc.write(body);
};
var i = 1;
var createWindow = function() {
var frame = document.getElementById('c' + i);
i++;
console.log('Setting src of frame')
frame.src = 'javascript:top.writeBody(document)';
console.log('Done setting src on frame');
};
jobs[jobs.length] = function() {
console.log('Invoking createWindow');
createWindow();
}
window.onload = function() {
creationManaer();
};