我试图尽快将iframe
元素附加到document.body
中。
在所有4种主要浏览器(Chrome,Safari,FF,IE等各种版本)中都会出现错误报告,我们看到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
逻辑,但是在IE中,当document.body
状态时,undefined
就是loading
。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
事件上的null
是否可能是DOMContentLoaded
?是否可能存在其他
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();
}
}
接下来,您的事件处理程序注册错误。
.addEventListener()
有3个参数,第三个可以是两个值之一:事件名称(字符串)
回调函数(引用或内联函数)
3a。是否挂接到捕获阶段(默认为boolean-
false
)3b。用于配置特征的选项对象(对象)
并且,在将接收事件的对象上调用
addEventListener()
本身(在本例中为window
)。它应该是:
window.addEventListener('DOMContentLoaded', function(){
this.appendIFrame.bind(this);
});
另外(FYI),您确实应该手动插入语句分号,而不要依赖自动插入,因为在某些情况下会导致错误。