简体   繁体   English

HTML 加载顺序和动态添加的 JS 文件

[英]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.我将一些 JS 文件动态添加到我的 HTML Header 中,并且我想保证我的 JS 文件在我继续呈现我的 Body 之前完成加载。
Events like load or DOMContentLoaded trigger after the loading is finished. load 或 DOMContentLoaded 等事件在加载完成后触发。
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. JS 的动态添加按预期工作。 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? 如何在动态添加的 js 文件中引用代码?

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.您可以改为从服务器加载相关的 HTML 内容(可能包括脚本标签),如果您真的想获得单页体验,或者启动导航,服务器将再次通过 HTTP 请求获取线索接下来生成。

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.但是,如果我们坚持这种模式,我会建议使用脚本元素的onload属性,并使用 promise 来等待所有脚本都已加载。

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.此演示在 AJAX 调用返回响应后加载两个 JS 文件:一个用于 immutablejs 库,第二个用于 momentjs 库。

A new Promise will resolve when the script's load event fires, and Promise.all will resolve when this has happened for all scripts.当脚本的load事件触发时,一个new Promise将被解析,当所有脚本都发生这种情况时, Promise.all将被解析。

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:出于演示的目的,我用模拟替换了 URL,并篡改了响应以生成您拥有的响应:

 // 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.备注:不推荐使用async: false选项。 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).而是使用 jQuery 为$.ajax$.get 、 ... 等返回的 Promise,并在继续处理结果的地方链接then调用(而不是success处理程序)。 And on once you arrive in the world of promises, you'll find that using async and await syntax can simplify code.一旦您进入 Promise 的世界,您会发现使用asyncawait语法可以简化代码。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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