This article was first published on my blog – blog.cdswyda.com. Be sure to retain the author and source for traceability and error correction.

The key point of this article is whether window.onload or ajax’s successful callback on the page fires first.

The answer is no.

Details on the problem

We encountered a phenomenon where a Dialog pops up on the parent page to load a child page, passing a parameter to the child page in the onLoad callback that is used in the child page’s asynchronous Ajax success callback.

What happens, however, is that most successful ajax callbacks don’t get the value passed in onload, but occasionally they do.

Looking at the Dialog source code, the above logic can be simplified as follows.

The parent page:

<iframe id="iframe" src="./iframe.html" onload="onLoad()" frameborder="0"></iframe>

<script>

function onLoad() {

console.log('iframe load');

document.getElementsByTagName('iframe')[0].contentWindow.onLoad('load');

}

</script>

Copy the code

Child pages:

<script>

$.ajax('./test.json').done(function (a) {

The console. The log (' ajax results');

console.log(a);

});

function onLoad(e) {

console.log('window onload')

console.log(e);

};

</script>

Copy the code

Since the onload of iframe is the window.onload of the page to load, the case can be further simplified to whether window.onload or ajax’s successful callback fires first in a page.

Test code:

<script>

$.ajax('./test.json').done(function (a) {

The console. The log (' ajax results');

console.log(a);

});



function onLoad(e) {

console.log('window onload')

console.log(e);

};

window.onload = onLoad;

</script>

Copy the code

This page has no code other than jQuery introduced before the test script, and it should be no surprise that window.onload is triggered first, followed by ajax success.

It turns out that window.onload is triggered first, and the above code will run in the browser:

// window onload

// Event {}

/ / ajax results

/ / {}

Copy the code

Window.onload (MDN) window.onload (MDN)

The load event fires at the end of the document loading process. At this point, all of the objects in the document are in the DOM, and all the images, scripts, links and sub-frames have finished loading.

The problem is that if window.onload must have been triggered first, then the original problem cannot have occurred.

Pseudo explain

Continue to modify the test code and add a few more things:

<script>

$.ajax('./test.json').done(function (a) {

The console. The log (' ajax results');

console.log(a);

});



function onLoad(e) {

console.log('window onload')

console.log(e);

};

window.onload = onLoad;

// Other code XXX

// Simulate a one-minute loop

var t1 = new Date().getTime();

while(new Date().getTime() - t1 < 1 * 60 * 1000) {

document.querySelectorAll('*');

}

</script>

Copy the code

After writing a one-minute loop, the result changes:

/ / ajax results

/ / {}

// window onload

// Event {}

Copy the code

It is surprising that Ajax’s success is triggered before window.onload.

I have no definitive explanation for this phenomenon.

Give yourself a “reasonable” analysis:

Window. onload is triggered last in the current task queue. As in the original example, ajax is asynchronous, the result hasn’t been given, everything the page needs to wait for has been done, and the task queue is empty, so window.onload fires.

This code delayed the onload trigger because there was a long code to execute behind ajax, and before the completion of this code, the asynchronous Ajax had already returned the result, and the successful callback code had been added to the task queue. So window.onload is triggered only after the Ajax callback is executed.

revalidation

To further test my ideas above, just make sure that ajax isn’t solved when the page resource execution completes.

So it’s the same code as above, but replace the requested content with a real interface that returns data later.

Pause PHP for 120s and return the result as follows:

<? php

sleep(120);

echo '{"response":"two minutes later."}'

? >

Copy the code

The result is as estimated above:

// window onload

// Event {}

/ / ajax results

// {"response":"two minutes later."}

Copy the code

Can show that the previous “reasonable” explanation is indeed reasonable.

So it’s uncertain whether asynchronous Ajax or window.onload will fire first, depending on your JS code (or any other resource onLoad is waiting for, such as an image that loads slowly) and how long the Ajax will take to resolve.

Therefore, the transfer of values in this case cannot be done in this way, but can be done in a more secure way, such as directly across the page or in the URL.