ChatGPT解决这个技术问题 Extra ChatGPT

如何在页面加载后执行 JavaScript?

我正在使用 <head> 内的 <script> 执行外部脚本。

现在,由于脚本在页面加载之前执行,因此我无法访问 <body> 等。我想在文档“加载”后执行一些 JavaScript(HTML 完全下载并在 RAM 中)。当我的脚本执行时,是否有任何可以在页面加载时触发的事件?


C
CommonSenseCode

这些解决方案将起作用:

如评论中所述,使用 defer

<script src="deferMe.js" defer></script>

或者

<body onload="script();">

或者

document.onload = function ...

甚至

window.onload = function ...

请注意,最后一个选项是更好的选择,因为它是 unobstrusiveconsidered more standard


和 document.onload=function ... 有什么区别?
@mentoliptus:document.onload= 不显眼en.wikipedia.org/wiki/Unobtrusive_JavaScript
@gerdi OP 没有提到任何关于 jQuery 的内容。我在回答中也给出了一个不显眼的选项。
document.onload 对我不起作用。我发现这篇文章有同样的问题stackoverflow.com/questions/5135638/…。似乎 document.onload 不是一个选项。
考虑到一旦准备好操作 DOM 就运行 javascript 的目标,这些选项中的 ALL 比必要的要晚得多。实现该目标的两个更好的选择:1) 在头部的 javascript 链接上使用 defer 属性。 2) 将访问 DOM 的任何 javascript 移动到页面底部,紧挨 </body> 之前。
D
DevWL

适时触发脚本

使用“延迟”

<script src="script.js" defer></script>

使用 defer 将在 domInteractive (document.readyState = "interactive") 之后和触发 "DOMContentLoaded" 事件之前触发。如果您需要在加载所有资源(图像、脚本)后执行脚本,请使用“加载”事件或以 document.readyState 状态之一为目标。进一步阅读以了解有关这些事件/状态的更多信息,以及与脚本获取和执行时间相对应的异步和延迟属性。

此布尔属性设置为向浏览器指示脚本将在文档被解析之后但在触发 DOMContentLoaded 之前执行。具有 defer 属性的脚本将阻止 DOMContentLoaded 事件触发,直到脚本加载并完成评估。

资源:https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script#attributes

* 请参阅底部的图像以了解羽毛说明。

事件监听器 - 请记住,页面的加载不止一个事件:

“DOMContentLoaded”

当初始 HTML 文档已完全加载和解析时触发此事件,无需等待样式表、图像和子框架完成加载。在这个阶段,您可以根据用户设备或带宽速度以编程方式优化图像和 CSS 的加载。在加载 DOM 之后执行(在图像和 CSS 之前):

document.addEventListener("DOMContentLoaded", function(){
    //....
});

注意:同步 JavaScript 会暂停 DOM 的解析。如果您希望在用户请求页面后尽快解析 DOM,您可以将 JavaScript 设为异步并优化样式表的加载

“加载”

在加载和解析所有内容后执行:

document.addEventListener("load", function(){
    // ....
});

MDN 资源: https://developer.mozilla.org/en-US/docs/Web/Events/DOMContentLoaded https://developer.mozilla.org/en-US/docs/Web/Events/load

所有事件的 MDN 列表:
https://developer.mozilla.org/en-US/docs/Web/Events

带有 radyStates 的事件侦听器 - 替代解决方案 (readystatechange):

// Place in header (do not use async or defer)
document.addEventListener('readystatechange', event => {
  switch (document.readyState) {
    case "loading":
      console.log("document.readyState: ", document.readyState,
       `- The document is still loading.`
       );
      break;
    case "interactive":
      console.log("document.readyState: ", document.readyState, 
        `- The document has finished loading DOM. `,
        `- "DOMContentLoaded" event`
        );
      break;
    case "complete":
      console.log("document.readyState: ", document.readyState, 
        `- The page DOM with Sub-resources are now fully loaded. `,
        `- "load" event`
        );
      break;
  }
});

MDN 资源:https://developer.mozilla.org/en-US/docs/Web/API/Document/readyState

在哪里放置你的脚本(有和没有异步/延迟)?

https://i.stack.imgur.com/jsHK7.jpg

https://i.stack.imgur.com/b3ixy.jpg

https://i.stack.imgur.com/GkezA.jpg

https://i.stack.imgur.com/zx3fh.jpg

如果您的脚本使用 asyncdefer,请阅读以下内容:https://flaviocopes.com/javascript-async-defer/


@Peter 很确定如果它在你的 javascript 文件的底部,那么它可能是最好的,所以它最后执行
这是最完整的答案。 onload 是之后,但人们一开始并没有意识到这一点。
关于异步javascript:澄清一下,对于不立即运行的脚本有两种选择。其中,defer 通常比 async 更可取——因为 defer 不会中断 html 解析/渲染——并且当它运行时,DOM 是有保证的做好准备。 Efficiently load JavaScript with defer and async
+1 我尝试 window.onload = ... 认为我的脚本会等到所有内容都完全下载后再运行,但看起来 window.onload 实际上的行为类似于 document.addEventListener("DOMContentLoaded", ...,而 window.addEventListener("load", ... 确实会等待所有内容都完全下载。我会认为 window.onload 应该等同于 window.addEventListener("load", ... 而不是 document.addEventListener("DOMContentLoaded", ... ??我在 Chrome 和 FF 中得到了相同的结果。
@DevWL,我认为您的意思是“延迟”......因为“异步”仍然可以在所有 html 加载之前执行。
c
chaos

让您的脚本设置一个在加载时运行的函数的合理可移植、非框架方式:

if(window.attachEvent) {
    window.attachEvent('onload', yourFunctionName);
} else {
    if(window.onload) {
        var curronload = window.onload;
        var newonload = function(evt) {
            curronload(evt);
            yourFunctionName(evt);
        };
        window.onload = newonload;
    } else {
        window.onload = yourFunctionName;
    }
}

+1 发布几乎完全是我 6 个月前想出的东西。如果您无法控制的其他框架和代码正在添加 onload 事件,并且您也希望在不清除其他 onload 事件的情况下添加此类代码,则可能需要这样的代码。我将我的实现作为一个函数包含在内,它需要 var newonload = function(evt) { curronload(evt);新加载(evt);因为由于某种原因,我使用的框架需要一个事件传递给 onload 事件。
我刚刚在测试中发现,编写的代码导致处理程序在附加 attachEvent() 时以未定义的顺序触发。如果处理程序执行的顺序很重要,您可能希望忽略 window.attachEvent 分支。
所以这会将此函数添加为运行 OnLoad 的附加函数,对吗? (而不是替换现有的 onload 事件)
@ClayNichols:正确。
很好的解决方案,但现在已过时:developer.mozilla.org/en-US/docs/Web/API/EventTarget/…
N
Nordes

您可以在正文中放置一个“onload”属性

...<body onload="myFunction()">...

或者,如果您使用的是 jQuery,您可以这样做

$(document).ready(function(){ /*code here*/ }) 

or 

$(window).load(function(){ /*code here*/ })

我希望它能回答你的问题。

请注意,$(window).load 将在您的页面上呈现文档后执行。


D
Daniel Price

如果脚本在文档的 <head> 中加载,则可以在脚本标记中使用 defer 属性。

例子:

<script src="demo_defer.js" defer></script>

来自 https://developer.mozilla.org

defer 这个布尔属性被设置为向浏览器指示脚本应该在文档被解析之后,但在触发 DOMContentLoaded 之前执行。如果 src 属性不存在(即对于内联脚本),则不得使用此属性,在这种情况下,它将不起作用。要为动态插入的脚本实现类似的效果,请改用 async=false。具有 defer 属性的脚本将按照它们在文档中出现的顺序执行。


我喜欢这个解决方案,因为不需要任何 javascript 代码,而只需要一个 html 属性 <3
这从根本上是错误的。 Defer 不会阻止执行后页面加载。 defer 和 async 脚本都在页面加载之前加载,而是改进了“domInteraction”时间。
@Akansh OP 只是想要一种方法来确保 DOM 在其脚本执行之前已加载。 Defer 这样做,它实际上是写在我在回答中共享的文档片段中。
看起来您可以在页面加载后使用 async false 进行内联脚本加载? “要为动态插入的脚本实现类似的效果,请改用 async=false。- 此布尔属性设置为向浏览器指示脚本应在文档被解析后但在触发 DOMContentLoaded 之前执行。”
L
Lucky

这是一个基于页面加载后延迟js加载的脚本,

<script type="text/javascript">
  function downloadJSAtOnload() {
      var element = document.createElement("script");
      element.src = "deferredfunctions.js";
      document.body.appendChild(element);
  }

  if (window.addEventListener)
      window.addEventListener("load", downloadJSAtOnload, false);
  else if (window.attachEvent)
      window.attachEvent("onload", downloadJSAtOnload);
  else window.onload = downloadJSAtOnload;
</script>

我在哪里放置这个?

将代码粘贴到 HTML 中的 标记之前(靠近 HTML 文件的底部)。

它有什么作用?

此代码表示等待整个文档加载,然后加载外部文件 deferredfunctions.js。

这是上述代码的示例 - Defer Rendering of JS

我根据 defered loading of javascript pagespeed google 概念写了这篇文章,也来自这篇文章 Defer loading javascript


我认为这个解决方案,结合 chaos 用户 (stackoverflow.com/a/807997/10712525) 的回答,将是你能做的最好的事情。
D
Daniel A. White

查看挂钩 document.onload 或 jQuery $(document).load(...)


这个活动靠谱吗? (跨浏览器.. IE6+ FF2+ 等)
是的,这是跨浏览器的标准 DOM。
实际上,更标准的是 window.onload,而不是 document.onload。 AFAIK
是在加载所有资源(如字体和图像)并正确更新视觉之前还是之后调用 onload
T
T.Todua

JavaScript

document.addEventListener('readystatechange', event => { 

    // When HTML/DOM elements are ready:
    if (event.target.readyState === "interactive") {   //does same as:  ..addEventListener("DOMContentLoaded"..
        alert("hi 1");
    }

    // When window loaded ( external resources are loaded too- `css`,`src`, etc...) 
    if (event.target.readyState === "complete") {
        alert("hi 2");
    }
});

jQuery 相同:

$(document).ready(function() {   //same as: $(function() { 
     alert("hi 1");
});

$(window).load(function() {
     alert("hi 2");
});

注意: - 不要使用以下标记(因为它会覆盖其他同类声明):

document.onreadystatechange = ...

T
TylerH
<script type="text/javascript">
  function downloadJSAtOnload() {
   var element = document.createElement("script");
   element.src = "defer.js";
   document.body.appendChild(element);
  }
  if (window.addEventListener)
   window.addEventListener("load", downloadJSAtOnload, false);
  else if (window.attachEvent)
   window.attachEvent("onload", downloadJSAtOnload);
  else window.onload = downloadJSAtOnload;
</script>

http://www.feedthebot.com/pagespeed/defer-loading-javascript.html


V
Viktor Borítás

Working Fiddle<body onload="myFunction()">

<!DOCTYPE html>
<html>
 <head>
  <script type="text/javascript">
   function myFunction(){
    alert("Page is loaded");
   }
  </script>
 </head>

 <body onload="myFunction()">
  <h1>Hello World!</h1>
 </body>    
</html>

e
ekostadinov

我有时会在更复杂的页面上发现,在 window.onload 被触发时并非所有元素都已加载。如果是这种情况,请在您的函数之前添加 setTimeout 以延迟片刻。它并不优雅,但它是一个简单的 hack,渲染效果很好。

window.onload = function(){ doSomethingCool(); };

变成……

window.onload = function(){ setTimeout( function(){ doSomethingCool(); }, 1000); };

r
rogerdpack

如果您使用的是 jQuery,

$(function() {...});

相当于

$(document).ready(function () { })

或另一种简写:

$().ready(function () { })

请参阅 What event does JQuery $function() fire on?https://api.jquery.com/ready/


A
Arthur Tsidkilov
document.onreadystatechange = function(){
     if(document.readyState === 'complete'){
         /*code here*/
     }
}

看这里:http://msdn.microsoft.com/en-us/library/ie/ms536957(v=vs.85).aspx


一行:document.onload = function() { ... }
f
fragilewindows

只需定义将在页面加载后调用的 <body onload="aFunction()">。您在脚本中的代码由 aFunction() { } 括起来。


M
MD SHAYON

DOMContentLoaded 事件在初始 HTML 文档完全加载和解析后触发,无需等待样式表、图像和子框架完成加载。

document.addEventListener('DOMContentLoaded', (event) => { console.log('DOM 完全加载并解析'); });

加载整个页面时会触发 load 事件,包括所有相关资源,例如样式表和图像。这与 DOMContentLoaded 不同,后者在页面 DOM 加载后立即触发,无需等待资源完成加载。

window.addEventListener('load', (event) => { console.log('页面已完全加载'); });


H
Hakan KOSE
<body onload="myFunction()">

这段代码运行良好。

但是 window.onload 方法具有各种依赖项。所以它可能不会一直有效。


K
Kamil Kiełczewski

比较

在下面的片段中,我收集了选择的方法并显示了它们的顺序。评论

任何现代浏览器都不支持 document.onload (X)(从不触发事件)

如果您使用 (F) 并同时使用 window.onload (E) 则只会执行第一个(因为它会覆盖第二个)

(F) 中给出的事件处理程序由附加的 onload 函数包装

document.onreadystatechange (D) 不覆盖 document.addEventListener('readystatechange'...) (C) 可能会导致类似 onXYZevent 的方法独立于 addEventListener 队列(允许添加多个侦听器)。执行这两个处理程序之间可能没有任何反应。

所有脚本都在控制台中写入它们的时间戳 - 但也可以访问 div 的脚本也在正文中写入它们的时间戳(在脚本执行后单击“整页”链接以查看它)。

解决方案 readystatechange (C,D) 由浏览器多次执行,但针对不同的文档状态: loading - 文档正在加载(在代码段中没有触发) interactive - 文档被解析,在 DOMContentLoaded 完成之前触发 - 文档和资源已加载,在正文/窗口加载之前触发

loading - 文档正在加载(没有在代码段中触发)

交互式 - 文档被解析,在 DOMContentLoaded 之前触发

完成 - 加载文档和资源,在正文/窗口加载之前触发


佚名

关于如何使用 Javascript 或 Jquery detect if document has loaded 有一个非常好的文档。

使用本机 Javascript 这可以实现

if (document.readyState === "complete") {
 init();
 }

这也可以在区间内完成

var interval = setInterval(function() {
    if(document.readyState === 'complete') {
        clearInterval(interval);
        init();
    }    
}, 100);

Eg By Mozilla

switch (document.readyState) {
  case "loading":
    // The document is still loading.
    break;
  case "interactive":
    // The document has finished loading. We can now access the DOM elements.
    var span = document.createElement("span");
    span.textContent = "A <span> element.";
    document.body.appendChild(span);
    break;
  case "complete":
    // The page is fully loaded.
    console.log("Page is loaded completely");
    break;
}

使用 Jquery 仅检查 DOM 是否准备就绪

// A $( document ).ready() block.
$( document ).ready(function() {
    console.log( "ready!" );
});

要检查是否所有资源都已加载,请使用 window.load

 $( window ).load(function() {
        console.log( "window loaded" );
    });

H
Harish Kumar

将此代码与 jQuery 库一起使用,这将非常好。

$(window).bind("load", function() { 

  // your javascript event

});

在此处添加一些描述
T
TylerH
$(window).on("load", function(){ ... });

.ready() 最适合我。

$(document).ready(function(){ ... });

.load() 会起作用,但不会等到页面加载完毕。

jQuery(window).load(function () { ... });

对我不起作用,会破坏下一个内联脚本。我还使用 jQuery 3.2.1 以及其他一些 jQuery 分支。

为了隐藏我的网站加载覆盖,我使用以下内容:

<script>
$(window).on("load", function(){
$('.loading-page').delay(3000).fadeOut(250);
});
</script>

C
Camel Djoulako

您可以在特定脚本文件上编写一个函数,并使用 onload 属性将其调用到您的 body 元素中。

示例:

<script>
  afterPageLoad() {
   //your code here
}
</script>

现在使用 script 标签将您的脚本调用到您的 html 页面中:

<script src="afterload.js"></script>

进入你的身体元素;像这样添加 onload 属性:

<body onload="afterPageLoad();">

请重新考虑您的回滚,这取消了有用的编辑。让其他用户提高帖子的可读性应该被认为是一件好事。
I
Iain

正如丹尼尔所说,您可以使用 document.onload。

各种 javascript 框架(jQuery、Mootools 等)都使用自定义事件“domready”,我想这一定更有效。如果您使用 javascript 进行开发,我强烈建议您使用框架,它们会大大提高您的工作效率。


V
Valentin Jacquemin

使用 YUI library(我喜欢它):

YAHOO.util.Event.onDOMReady(function(){
    //your code
});

便携又漂亮!但是,如果您不将 YUI 用于其他东西(请参阅其文档),我会说不值得使用它。

注意:要使用此代码,您需要导入 2 个脚本

<script type="text/javascript" src="http://yui.yahooapis.com/2.7.0/build/yahoo/yahoo-min.js" ></script>
<script type="text/javascript" src="http://yui.yahooapis.com/2.7.0/build/event/event-min.js" ></script>

K
Kalidass

我的建议是使用 asnyc 属性作为脚本标签,这可以帮助您在页面加载后加载外部脚本

<script type="text/javascript" src="a.js" async></script>
<script type="text/javascript" src="b.js" async></script>

根据 w3schools如果存在异步:脚本与页面的其余部分异步执行(脚本将在页面继续解析时执行)。也许您的意思是 defer,就像提到的@Daniel Price 一样?
J
Jared Lovin