Script onload happens after window onload in JSDOM

2020-08-04 04:42发布

问题:

This is a new question arising from what I learnt in: Is order of script onload and window.onload well defined when the script is a DOM node created dynamically from a loaded script?

In the previous question we learnt that when a window is loading scripts, any scripts (the one directly loaded as well as the ones dynamically being loaded by the script) would finish loading first and only after that the window.onload will fire.

But JSDOM seems to be behaving differently.

Here is the loader.js script which is same as the one in the previous question:

function main()
{
  if (typeof window !== 'undefined') {
    var script = window.document.createElement('script')
    script.src = 'https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.core.min.js'
    script.onload = function () { console.log('script loaded') }
    window.onload = function () { console.log('window loaded') }
    window.document.head.appendChild(script)
  } else {
    console.log('window not available yet')
  }
}

if (typeof module !== 'undefined' && module.exports) {
  exports.main = main
}

main()

Here is the driver code that pretends to be a fake window via JSDOM.

var jsdom = require('jsdom')
var loader = require('./loader.js')

var html = `<!DOCTYPE html>
<html>
  <head>
    <title>Test</title>
    <script src="loader.js"></script>
  </head>
  <body>
    <div>Test</div>
  </body>
</html>`

global.window = new jsdom.JSDOM(html, { runScripts: "dangerously", resources: "usable" }).window

This is the output:

$ node fakewindow.js 
window not available yet
window loaded
script loaded

The window.onload event fired before the script.onload event fire. Why did JSDOM consider the window loaded even when a dynamic script loaded by a script directly included in the HTML hadn't loaded yet? Is this a bug in JSDOM or is this behavior allowed by relevant W3C standards?

回答1:

Seems like a bug in JSDOM.

It appears to be solved in the latest version 13.0.0, try updating JSDOM.

I've tried out the same code for jsdom 13 and it works.

window not available yet
script loaded
window loaded

while jsdom 11 indeed shows the problem:

window not available yet
window loaded
script loaded