很长一段时间以来,我一直认为这是一个“绝对的事实”:
let img = new Image();
img.src = '... some url ...'
img.onload = function() { console.log('onload') }
是
错误的
,因为
.onload
可能无法调用处理程序。使用附加处理程序也是一样的
.addEventListener('load', function() ... )
设置后
.src
:可能不起作用。(看这个
example answer
声明如下:“…在为src属性赋值之前添加事件侦听器…”)
这个问题的背景:我找到了一个设置的例子
.src
打电话之前
.addEventListener
在流行的p5.js库中,特别是
here
。我想解决这个问题并提交一个PR。但是,我也想创建一个单元测试
失败
使用当前代码(设置
.src =
打电话之前
.addEventListener
和
通过
用我的补丁。
然而我还没能真正看到在什么情况下设置
.src
之前真的失败了。。。!
以下是一些代码来演示我的意思:
(function f() {
let i = new Image();
i.src = '//placekitten.com/10/10';
document.querySelector('body').appendChild(i);
let out = 0;
for(let i = 0; i < 1000000000; i++) { out *= i * 100 - out * 2; } // just to delay
i.onload = function() { console.log('onload') }
i.addEventListener('load', function() { console.log('load event') });
})();
1000000000次迭代循环需要几秒钟才能完成,因为我正试图获得
Image
元素和要尽早加载的图像URL,以便
.加载
和
.addEventListener
处理程序将失败。。。但它们有效!
我试着用一个很短的数据URL代替placekitten.com,结果是一样的。在运行测试代码之前,我尝试加载placekitten.com和数据URL图像(以确保这些图像被缓存),但这也不起作用。
我唯一能得到的方法
.加载
和
.addEventListener
不被调用的处理程序是将它们包装在
setTimeout
...
JavaScript的单一线程性是否使以下“事实”无效
.src
应该始终在设置事件侦听器之后进行设置吗?或者这是现代浏览器中发生的变化,而在旧的浏览器中也是如此
.src
在连接侦听器之前有时会失败?谢谢