【问题标题】:window.onload seems to trigger before the DOM is loaded (JavaScript)window.onload 似乎在加载 DOM 之前触发(JavaScript)
【发布时间】:2010-03-20 23:56:03
【问题描述】:

我在处理 window.onloaddocument.onload 事件时遇到了问题。我读到的所有内容都告诉我,在 DOM 完全加载其所有资源之前,这些不会触发,看来这对我来说并没有发生:

我在 Chrome 4.1.249.1036 (41514) 和 IE 8.0.7600.16385 中尝试了以下简单页面,结果相同:都显示消息“失败!”,表示未加载 myParagraph(因此 DOM似乎不完整)。

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
    <head>
        <script type="text/javascript">
            window.onload = doThis();
            // document.onload gives the same result

            function doThis() {
                if (document.getElementById("myParagraph")) {
                    alert("It worked!");
                } else {
                    alert("It failed!");
                }
            }
        </script>
    </head>

    <body>
        <p id="myParagraph">Nothing is here.</p>
    </body>
</html>

我在外部 .js 文件中使用了比这更复杂的脚本,但这说明了问题。我可以通过让window.onload 设置一个半秒的计时器来运行doThis() 来让它工作,但这似乎是一个不优雅的解决方案,并且没有回答为什么window.onload 似乎没有做什么的问题每个人都说有。另一种解决方案是设置一个计时器来检查 DOM 是否已加载,如果没有,它将在半秒后调用自身(因此它将继续检查直到 DOM 加载完毕),但这对我来说似乎过于复杂。

有没有更合适的事件可以使用?

【问题讨论】:

  • 我看到的第一个错误是您评估 [function result] 而不是 [function] 本身。你能看到doThis() 是一个在评估后返回未定义的语句,因为doThis 没有return 运算符。 window.onload = doThis; 将完成这项工作。注意没有括号
  • @DavidMason W3Schools 的信息来源很差。他们不以任何方式隶属于 W3C。 不要将 w3schools 视为权威的信息来源,以应有的方式对待它们:在搜索真正的参考网站时必须跳过的令人讨厌的链接。
  • @doug65536 现在的我完全同意。我向不确定的人推荐 w3fools.com。这些天我倾向于直接去 developer.mozilla.org 获取高质量的信息,然后如果我在那里找不到我想要的东西(通常是当我试图做一些荒谬的事情时),请进行更广泛的搜索)。我很尴尬,过去的我发布了……但我可以删除它!在那里,互联网上对 w3schools 的引用不那么天真了 :) 感谢您发现它。

标签: dom dom-events getelementbyid onload onload-event


【解决方案1】:

只需使用window.onload = doThis; 而不是window.onload = doThis();

【讨论】:

【解决方案2】:

在加载窗口时,主体尚未加载,因此您应该按以下方式更正代码:

<script type="text/javascript">
    window.onload = function(){
        window.document.body.onload = doThis; // note removed parentheses
    };

    function doThis() {
        if (document.getElementById("myParagraph")) {
            alert("It worked!");
        } else {
            alert("It failed!");
        }
    }
</script>

经过测试,可以在 FF/IE/Chrome 中运行,但也在考虑处理 document.onload

如前所述,使用 js-frameworks 将是一个更好的主意。

【讨论】:

  • 谢谢,这似乎解决了我的问题,并解决了我认为在知道正文是否已成功加载之前将某些东西附加到 body.onload 事件的相同问题的递归。我现在收到消息“它成功了!”弹出,并且可以继续迂腐地保持我的脚本和标记的美观和独立。
  • 请注意,对 2 个脚本使用这种方法可能会用另一个覆盖其中一个。这些天我倾向于使用 document.addEventListener("DOMContentLoaded", function(event) { console.log("DOM fully loaded and parsed"); });见:developer.mozilla.org/en-US/docs/Web/Reference/Events/…
  • @DavidMason DomContentLoaded 在我的测试中加载之前加载。有时,speechSynthesis.getVoices() 在 load 事件和 DOMContentLoaded 事件上是一个空数组。以后有活动吗?
  • @1.21gigawatts 我不知道你的speechSynthesis.getVoices() 应该如何加载,所以寻找内容加载可能不是要做的事情 - 如果有一个脚本加载它那么你需要您的脚本尝试使用它出现在该脚本之后(并且没有将该脚本标记为异步)。
  • @DavidMason SpeechSynthesis 是 windows 对象的一个​​属性。 getVoices 调用获取文本到语音的列表。有时它是空的。一个简单的页面刷新,它就可用了。我为解决这个问题所做的工作是首先在 dom 内容加载和加载时进行调用并将其分配给一个数组,然后如果用户访问语音数组,我会检查该数组是否为空并再次调用它。这似乎做到了。 developer.mozilla.org/en-US/docs/Web/API/SpeechSynthesis
【解决方案3】:

了解() 是一个运算符 很重要,就像+&amp;&amp; 一样。 () 获取一个函数并调用它。

所以在这种情况下,doThis 是一个函数对象,() 是调用该函数的运算符。 doThis() 组合在一起调用doThis,执行它,并计算出doThis 的返回值

所以window.onload = doThis()基本上就是将doThis的返回值赋值给window.onload

因此,要解决这个问题,您需要引用函数本身,而不是调用它。

window.onload = doThis

【讨论】:

  • 这应该是答案。
【解决方案4】:

您是否尝试过使用 javascript 库,例如jQuery$(document).ready() 函数:

  $(document).ready(function() {
      // put all your jQuery goodness in here.
  });

【讨论】:

  • 谢谢,我这周去看看。我仍然担心似乎没有任何与 DOM 相关的事件可以可靠地告诉我 DOM 何时加载,而无需借助第三方脚本。
  • 为此添加一个库绝对是矫枉过正——库下载会增加延迟和数据传输,并且可能只会为您节省几个字符。 jQuery 特别重量级。话虽如此,如果您已经将库用于其他事情,那么使用它来处理将函数附加到 dom-ready 事件可能几乎没有害处。
  • @David Mason 我完全同意。大多数情况下,我发现 jquery 双倍页面加载时间..
  • @JamesWalker 如果您从 CDN 加载 jquery(或任何其他流行的 javascript 库),那么您的浏览器很有可能已经在其缓存中包含 js 文件(来自访问其他网站),因此加载时间不会显着增加。
【解决方案5】:

这取决于您将 onload 函数放置在何处(head 或 body 标签或更下方),内部事件绑定在不同浏览器中似乎略有不同。

另请参阅 window.onload vs document.onload

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-05-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多