gpt4 book ai didi

javascript - 我可以在加载整个页面之前运行 javascript 吗?

转载 作者:IT王子 更新时间:2023-10-29 02:46:45 27 4
gpt4 key购买 nike

我想在整个页面加载之前运行一些 javascript。这可能吗?或者代码是否开始在 </html> 上执行?

最佳答案

你不仅可以,而且如果你不想,你必须特别努力不要。 :-)

当浏览器遇到经典script在解析 HTML 时,它会停止解析并移交给运行脚本的 JavaScript 解释器。解析器在脚本执行完成之前不会继续(因为脚本可能会执行 document.write 调用以输出解析器应该处理的标记)。

这是默认行为,但您有一些延迟脚本执行的选项:

  • 使用 JavaScript 模块。一个 type="module"脚本被推迟到 HTML 被完全解析并创建初始 DOM。这不是使用模块的主要原因,但这是原因之一:
    <script type="module" src="./my-code.js"></script>
    <!-- Or -->
    <script type="module">
    // Your code here
    </script>

    代码将被提取(如果它是单独的)并与 HTML 解析并行解析,但在 HTML 解析完成之前不会运行。 (如果你的模块代码是内联的而不是在它自己的文件中,它也会被推迟到 HTML 解析完成。)

    当我在 2010 年第一次写这个答案时,这是不可用的,但在 2020 年,所有主要的现代浏览器都原生支持模块,如果你需要支持旧浏览器,你可以使用 Webpack 和 Rollup.js 之类的捆绑器。
  • 使用 defer经典脚本标签上的属性:
    <script defer src="./my-code.js"></script>

    与模块一样,my-code.js 中的代码将与 HTML 解析并行获取和解析,但在 HTML 解析完成之前不会运行。 但是 , defer不适用于内联脚本内容,仅适用于通过 src 引用的外部文件.
  • 我认为这不是您想要的,但您可以使用 async属性告诉浏览器在解析 HTML 的同时获取 JavaScript 代码,然后尽快运行它,即使 HTML 解析没有完成。你可以把它放在 type="module"标记,或使用它代替 defer在经典 script标记。
  • script标记在文档末尾,就在结束之前 </body>标签:
    <!doctype html>
    <html>
    <!-- ... -->
    <body>
    <!-- The document's HTML goes here -->
    <script type="module" src="./my-code.js"></script><!-- Or inline script -->
    </body>
    </html>

    这样,即使代码一遇到它就运行,它上面的 HTML 定义的所有元素都存在并且可以使用。

    过去,这会在某些浏览器上造成额外的延迟,因为它们直到 script 才会开始获取代码。遇到标签,但现代浏览器会提前扫描并开始预取。尽管如此,这在这一点上仍然是第三种选择,模块和 defer是更好的选择。

  • 规范 has a useful diagram显示原始 script标签, defer , async , type="module" , 和 type="module" async以及获取和运行 JavaScript 代码的时间:

    enter image description here

    这是默认行为的示例,原始 script标签:

    .found {
    color: green;
    }
    <p>Paragraph 1</p>
    <script>
    if (typeof NodeList !== "undefined" && !NodeList.prototype.forEach) {
    NodeList.prototype.forEach = Array.prototype.forEach;
    }
    document.querySelectorAll("p").forEach(p => {
    p.classList.add("found");
    });
    </script>
    <p>Paragraph 2</p>


    (有关该 NodeList 代码的详细信息,请参阅 my answer here。)

    当您运行它时,您会看到“第 1 段”为绿色,而“第 2 段”为黑色,因为脚本与 HTML 解析同步运行,因此它只找到第一段,而不是第二段。

    相比之下,这是一个 type="module"脚本:

    .found {
    color: green;
    }
    <p>Paragraph 1</p>
    <script type="module">
    document.querySelectorAll("p").forEach(p => {
    p.classList.add("found");
    });
    </script>
    <p>Paragraph 2</p>


    注意它们现在都是绿色的;代码直到 HTML 解析完成后才运行。对于 defer 也是如此 script与外部内容(但不是内联内容)。

    (不需要 NodeList 检查那里,因为任何现代浏览器支持模块已经在 forEach 上有 NodeList 。)

    在这个现代世界中, DOMContentLoaded 没有真正的值(value)。 PrototypeJS、jQuery、ExtJS、Dojo 和大多数其他人在当天提供(并且仍然提供)的“就绪”功能的事件;只需使用模块或 defer .即使在过去,也没有太多理由使用它们(而且它们经常被错误地使用,在加载整个 jQuery 库时阻止页面呈现,因为 scripthead 中而不是在文档之后), 某事 some developers at Google很早就被标记了。这也是 YUI recommendation 的部分原因将脚本放在 body 的末尾,再次回到当天。

    关于javascript - 我可以在加载整个页面之前运行 javascript 吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2920129/

    27 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com