onload 或 addEventListener 以及设置图像的 src 的顺序真的重要吗?



我认为这是一个"绝对的真理";很长一段时间,做:

let img = new Image();
img.src = '... some url ...'
img.onload = function() { console.log('onload') }

错误的,因为.onload处理程序可能不会被调用。在设置.src后使用.addEventListener('load', function() ... )附加处理程序也是同样的事情:它可能不起作用。(请看这个示例回答:"…在给src属性赋值之前添加事件侦听器…")


这个问题的上下文:我在流行的p5.js库中找到了一个在调用.addEventListener之前设置.src的示例,特别是在这里。然而,我也想创建一个单元测试,失败与当前代码(设置.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') });
})();

10000000000 -迭代循环需要几秒钟才能完成,因为我正试图将Image元素添加到DOM中,并尽早加载图像URL,以便.onload.addEventListener处理程序失败…但它们确实有效!

我尝试了一个非常短的数据URL,而不是placekitten.com,同样的结果。在运行测试代码之前,我尝试加载placekitten.com和数据URL图像(以确保这些图像被缓存),但这也不起作用。

我可以得到.onload.addEventListener处理程序不被调用的唯一方法是将它们包装在setTimeout


JavaScript的单线程性是否使"真值"无效?设置事件监听器后,.src应该始终设置?或者这是在现代浏览器中发生的变化,以前在旧浏览器中设置.src在附加侦听器之前有时会失败?谢谢!

顺序不重要。在同步执行完成后,load事件总是异步触发(通过加载算法在事件循环中排队),并将评估安装了哪些事件侦听器并且只在那时需要执行。

给出你链接的答案,尤其是图片。onload事件和浏览器缓存/jQuery回调图像加载(即使图像被缓存),它似乎旧的浏览器可能会触发事件同步(或根本不),如果图像从缓存加载。

最新更新