我正在尝试尽快将iframe
元素附加到document.body
中。
错误报告都在所有4个主要浏览器(Chrome,Safari,ff,IE - Various版本(中介绍,我们看到document.body
是null
。我认为当我的JS文件被缓存并迅速加载时,就会发生这种情况。
这是插入iframe
的逻辑:
private loadIFrame(): void {
switch (document.readyState) {
case 'uninitialized':
case 'loading':
case 'loaded':
window.addEventListener('DOMContentLoaded',
this.appendIFrame.bind(this)
)
break
case 'interactive':
case 'complete':
default:
this.appendIFrame()
}
}
private appendIFrame(): void {
if (document.getElementById('iframeId')) {
return
}
let iFrame: HTMLIFrameElement = document.createElement('iframe')
iFrame.src = document.location.protocol + this.ORIGIN + '/iframe.html'
iFrame.id = 'iframeId'
// document.body is null here
document.body.appendChild(iFrame)
}
我很难在干净的环境中重现问题,这让我猜测这是如何在野外发生的。
我最初尝试了此rreadyState
逻辑,但是我们在loading
状态时看到document.body
是IE中的undefined
。
private loadIFrame(): void {
switch (document.readyState) {
case 'uninitialized':
case 'loading':
window.addEventListener('DOMContentLoaded',
this.appendIFrame.bind(this)
)
break
case 'loaded':
case 'interactive':
case 'complete':
default:
this.appendIFrame()
}
}
我目前的询问...
- 问题是
default
情况吗?我应该在那里添加活动听众吗?我可以修改案件的顺序,以便默认事件侦听器? -
body
是否可能是DOMContentLoaded
事件上的null
? - 是否还有其他
document.readyState
值掉落了?
首先,如果您已经检查了readyState
并确定为loaded
,那么为什么要设置一个已经通过的事件处理程序(DOMContentLoaded
(?
您可以做:
private loadIFrame(): void {
switch (document.readyState) {
case 'uninitialized':
case 'loading':
case 'loaded':
this.appendIFrame.bind(this);
break;
case 'interactive':
case 'complete':
default:
this.appendIFrame();
}
}
接下来,您的活动处理程序注册是错误的。有3个参数到 .addEventListener()
,第三个可以是两个值之一:
- 事件名称(字符串(
回调函数(参考或内联函数(
3a。是否挂接捕获阶段(默认情况下为boolean -
false
(3b。配置特征(对象(的选项对象
和,addEventListener()
本身在接收事件的对象上被调用(在这种情况下为window
(。
应该是:
window.addEventListener('DOMContentLoaded', function(){
this.appendIFrame.bind(this);
});
另外(仅供参考(,您确实应该手动插入您的语句结尾半彩色,而不是依靠自动插入,因为在某些边缘情况下会导致错误。
我更新了逻辑,我能够几乎消除错误,但是当readyState
是interactive
时,我仍然看到document.body
是null
。
评估引起问题的特定浏览器方案后,我将更新此帖子。
private loadIFrame(): void {
switch (document.readyState) {
case 'uninitialized':
case 'loading':
case 'loaded':
document.addEventListener('DOMContentLoaded',
this.appendIFrame.bind(this)
)
break
case 'interactive':
case 'complete':
default:
if(document.body) {
this.appendIFrame()
} else {
window.addEventListener('load',
this.appendIFrame.bind(this)
)
}
}
}