简体   繁体   中英

Run JavaScript after all window.onload scripts have completed?

I have an asp.net page that loads some JavaScript scripts. One of those scripts loads some controls into the page appending them to the body in the window.onload event.

I need to inject a script via code behind to call a method of the scripts that depends on the controls created in the window.onload . This doesn't work because every call I make it's always to early and the controls are not created at the moment. If I call it by, for instance, onclick in an hyperlink it works because the controls were already created in the onload .

So:

  1. <script type="text/javascript" src="/Scripts/somefile.js"></script>

  2. addEvent(window, "load", blabla); - the js above prepares some controls to be appended to the body on the onload event

  3. In the code behind I try to write a script to the page by this.Page.ClientScript.RegisterStartupScript or this.Page.ClientScript.RegisterClientScriptBlock or whatever way that should call a method on the.js above, which depends on the control loaded on the onload event. This step fails because the control is not in the DOM yet.

Any suggestion on how make the call after the window.onload event?

create an array of functions:

<script>
  var onLoadFunctions = [];

  function addOnLoad(funcName) {
    onLoadFunctions[onLoadFunctions.length] = funcName;
  }

  function executeOnLoad() {
    for (var i=0; i<onLoadFunctions.length; i++) onLoadFunctions[i]();
  }

  addOnLoad(foobar);
  addOnLoad(blabla);
  addOnLoad(theother);

  window.onload = executeOnLoad;
</script>

If you can use jQuery

then you can call the script after the DOM load is complete.

$(document).ready()

Introducing $(document).ready()

您可以像注册启动脚本一样注册js文件:

this.Page.ClientScript.RegisterClientScriptInclude("scriptKey", "/Scripts/somefile.js");

Using Prototype JavaScript , you can have scripts called when the DOM is ready ( see the API here ):

document.observe("dom:loaded", function() {
  alert('The DOM is ready.');
});

I would recommend moving the script that loads in the onload event to the dom:loaded event.

Instead window.onload, you can use document.onreadystatechange event for this,, below the sample snippet..

document.onreadystatechange=onReady;
  function onReady() {
      if (document.readyState=="complete") {
         alert('The document ready state is "complete"') 
      }

I tried several approaches with no success. I just changed the business requirement and the script is fired by an user action, as opposed to a script injected via code behind.

But for someone looking for an answer, there are several possible candidates that may solve the problem in your case.

Use timeout within onLoad to schedule your script to run later.

function mustRunLast () {
    // your "must run after everything else" code here
}

document.addEventListener('load', function(){
    // adjust the delay as you like, 500 millis is a bit long
    setTimeout(mustRunLast, 500)
})

The above forces you to guess how long it will take for your other onLoad scripts to finish. To play it safe, you'd have to use a long delay, but that is probably undesirable. But if you have some state that you can check to verify that the other scripts you're depending on have run, you can use a short delay and have the script keep retrying until things are ready:

Have your script check if things are ready, and schedule a retry for later if not

const mustRunLast = function() {
    // check some state to see if the other scripts
    // did their thing. If not, schedule self to retry later
    if (<not ready yet>) {
        setTimeout(mustRunLast, 50)
        return
    }
     
    // your "must run after everything else" code here
}

document.addEventListener('load', mustRunLast)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM