确保我的 .JS 文件每次都先于其他文件加载

Make sure my .JS file loads every time before others

我有一个无法访问源代码的网站,但我可以使用 Javascript 对其进行操作。我有一个名为 main.js 的文件,该文件包含在我有权访问的包含的最后,我想 运行 我的自定义 Javascript 代码在该文件中。我的服务器上有一个 .JS 文件,其中包含一个名为 helloWorld() 的函数,我想在任何 $(document).ready() 回调触发之前加载它,因为我网站上的 $(document).ready() 函数之一page/pages 使用此功能。

自定义 .JS 文件:

function helloWorld()
{
alert("Hello World");
}

main.js 服务器上的文件(可访问):

//All the JS code that the website uses
..

// My custom javascript code that includes my custom .JS file
$.getScript("helloWorld.js", function()
{
   // Use anything defined in the loaded script...
});

现在我想在页面加载时加载 helloWorld(),然后再触发任何 $(document).ready() 函数。我知道在加载页面时加载此 .JS 文件可能会减慢页面加载速度。是否有一种万无一失的方法来确保我的自定义 javascript 函数将在任何 $(document).ready() 函数之前加载?如果有任何其他方法可以实现此目的,请告诉我。期待您的建议。

据我所知,有多种方法可以做到这一点,但最好的方法是使用 Require.js 或 CommonJS 之类的东西来解决你的依赖关系,连接它们,然后发布结果串联 javascript 个文件(如果您可以将您的应用分成多个部分,则可以是多个文件)。

不太好的方法是使用主脚本通过添加脚本标签来加载其他脚本,这样你可以确保它在那里,因为它加载了其他脚本。

看来我找到了解决您问题的方法。我不建议这样做,但这是在 DOMContentLoaded 事件触发之前从另一个脚本加载外部脚本的唯一方法。

解决方案

由于您的 main.js 脚本位于文档的 <head> 中,您可以确定它将在 DOM 的任何后续部分之前加载和执行。鉴于此,您可以使用同步 XMLHttpRequest 加载脚本并执行它

这种技术有利也有弊:

  • 优点:你可以在DOMContentLoaded之前加载和执行任何脚本,也可以顺序加载和执行多个脚本。

  • 缺点: 在请求完成之前,您的文档将被冻结。

还不错,如果您的脚本不是很大,它不会显着影响加载时间。我们仍然可以做到。

实施

首先,请确保您的 custom.js 脚本通过 link 提供服务,该 link 始终可以访问,这样您的请求就不会失败。还要确保您的 main.js 脚本没有 asyncdefer 属性,以便它始终在 <head> 中执行,然后在 DOMContentLoaded 中执行事件。

<!-- NOT GOOD -->
<script src="main.js" defer></script>
<script src="main.js" async></script>

<!-- GOOD :) -->
<script src="main.js"></script>

现在您已准备就绪,在您的 main.js 脚本中,您需要:

  1. 创建并初始化同步 XMLHttpRequest 对象,并 send() 对您的 content.js 脚本发出 GET 请求。

  2. 创建一个<script>元素,把你请求的结果(存储在请求对象的.responseText属性中)放在里面。

  3. 在加载 DOM 之前将脚本附加到 <head> 使其成为 运行。

此外,如果您还希望在执行后立即删除脚本(这样用户就看不到它),您可以:

  1. 在 运行 代码后从文档中删除 <script>。为此,您需要监听 onload 事件。

此外,如果您想使您的代码 运行 完全匿名,您可以将其包装在匿名 function 中以防止从全局范围访问它。

这是您需要在 main.js 文件中执行的操作的简单示例:

(function() {
    // Create the request and the script
    var xhr = new XMLHttpRequest(),
        s = document.createElement('script');

    // Send the request to retrieve custom.js
    xhr.open('GET', 'path/to/custom.js', false);
    xhr.send();

    // Listen for onload, and remove the script after execution
    s.addEventListener("load", function(e) {
        s.parentElement.removeChild(s);
    });

    // Load the code inside the script and run it in the head
    s.textContent = xhr.responseText;
    document.head.appendChild(s);
})();

现在您的 custom.js 脚本将在 DOMContentLoaded 之前(匿名)运行,任务完成!