简体   繁体   中英

HTML load order and dynamically added JS Files

I add some JS files dynamically to my HTML Header and I want to guarantee that my JS files finish loading before I continue to render my Body.
Events like load or DOMContentLoaded trigger after the loading is finished.
my body needs the added scripts to render properly but starts before the files are loaded fully.

Code Snippet:

    ...
    <script>

            $.ajax({
                type: "Get",
                url: '@Url.Action("GetLocalisationFiles", "Localisation")',
                success: function (response) {
                        for (var file in response) {
                            var scriptName = response[file];
                            //Adding of the script(s)
                            let myScript = document.createElement("script");
                            myScript.setAttribute("src", scriptName);
                            document.head.appendChild(myScript);
                            //
                        }
                }
            });

        window.addEventListener("load", LocalizationAdded);
        function LocalizationAdded(e) {
            alert("JS Files Finished Loading");
            DevExpress.localization.loadMessages(RddsDataNavigator_LanguagePack_en);

        }
    </script>
</head>

<body class="dx-viewport">
    <script>
        alert("Body Started"); 
        ...

Is there any other event prior to the rendering of the body or an easy way to delay my body rendering?
I know I could manually add all Content that depends on the added scripts after the loading is finished but this seems fuzzy.
The dynamical adding of JS works as intended. My Problem is within the order it happens.

Thanks in advance for any help

Previous question:
How do I reference code in dynamically added js files?

We could question whether loading scripts following some user action, is such a good idea. You could instead load the relevant HTML content from the server (which could include script tags), if you really want to have a one-page experience, or else initiate a navigation, where again the server would get clues via HTTP request on what to generate next.

But, if we stick with this pattern, I would suggest using the onload property of script elements, and to use promises for awaiting all scripts to have been loaded.

Here is some code you could use. This demo loads two JS files after an AJAX call has come back with a response: one for the immutablejs library, the second for the momentjs library.

A new Promise will resolve when the script's load event fires, and Promise.all will resolve when this has happened for all scripts.

For the purpose of demo I replaced the URL with a mock, and also tampered with the response in order to produce a response as you have it:

 // dummy server, just for demo let url = "https://jsonplaceholder.typicode.com/todos/1"; console.log("Launching initial HTTP request..."); $.get(url).then(function (response) { console.log("Received response. Loading scripts..."); // Overwriting the response with mock data: response = { immutable: "https://cdnjs.cloudflare.com/ajax/libs/immutable/3.8.2/immutable.min.js", moment: "https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.15.0/moment.min.js" }; return Promise.all(Object.values(response).map(function (scriptName) { return new Promise(function (resolve, reject) { //Adding of the script(s) let myScript = document.createElement("script"); myScript.setAttribute("src", scriptName); myScript.onload = resolve; myScript.onerror = reject; document.head.appendChild(myScript); // }); })); }).then(function () { // All code that depends on the loaded scripts should be here, or called from here console.log("All scripts loaded:"); console.log("Immutable: ", typeof Immutable); console.log("moment: ", typeof moment); });
 <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

Remark: the async: false option is deprecated. It is not good practice either. Instead use the Promise that jQuery returns for $.ajax , $.get , ...etc, and chain a then call where you continue processing the result (instead of a success handler). And on once you arrive in the world of promises, you'll find that using async and await syntax can simplify code.

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