JavaScript事件window.onload未被触发

69

我有一个网站中的以下代码:

 window.onload = resize;
 window.onresize = resize;

 function resize(){
  heightWithoutHeader = (window.innerHeight - 85) + "px"; 
  document.getElementById("main-table").style.height = heightWithoutHeader;
  document.getElementById("navigation").style.height = heightWithoutHeader;
 }

onresize 事件正常工作,但是 onload 事件从未触发。我已经在 Firefox 和 Chrome 中尝试过它们都不起作用。

感谢您的帮助,祝您赚取更多声望!;D


7
你什么时候运行这段代码?onload事件是否可能被后续覆盖或在load事件触发后再进行绑定? - Nick Craver
你是对的。window.onload 显然被后来的 <body onload=...> 覆盖了。请将您的评论作为答案发布,这样我就可以将其选为正确答案。 - user321068
做得好 :) 很高兴你解决了它! - Nick Craver
12个回答

126

我认为这里可能发生的情况是你的window.onload被后面的内容覆盖了,检查一下是否是通过类似<body onload="">这样的方式覆盖了它。

你可以在你的重新调整大小的函数中使用alert(window.onload)来检查,看看实际上附加了什么内容。


1
我不知道如果你在多个.js文件中有window.onload,它会被覆盖,这很合理,但知道这一点还是很好的! - Shmack
一个小提示,针对有类似问题的人。在我的情况下,我使用了动态HTML,通过win = window.open("about:blank","",""); win.document.write(htmlcontent);在文档内填充。但是我的JavaScript表单提交操作从未被触发,因为onload事件没有被调用。我通过这个答案添加了win.onload(null);,然后它就起作用了。 - LysanderM
重要的是要说,window.onload事件可以在body onload代码触发后剪切并粘贴到脚本下面。然后window.onload脚本也会起作用。 - Benjamin

46

当我添加第三方jQuery代码以满足合作伙伴需求时,出现了这种情况。 我本可以轻松地将过时的window.onload转换为jQuery文档准备就绪。 话虽如此,我想知道是否有现代的、跨浏览器兼容的解决方案。

是有的!

window.addEventListener ? 
window.addEventListener("load",yourFunction,false) : 
window.attachEvent && window.attachEvent("onload",yourFunction);

现在我知道...我可以将我的代码转换成使用jQuery的方式。而且,我会要求我们的合作伙伴重构他们的代码,以便停止影响站点。

我找到解决方案的来源 --> http://ckon.wordpress.com/2008/07/25/stop-using-windowonload-in-javascript/


我不知道为什么,但这段代码对我不起作用。我用我的函数 runCode 替换了 yourFunction ,甚至像下面建议的那样将 addEventListener 代码移到了我的脚本底部。 - Shayan
我知道三元运算符,但我不明白 window.addEventListener ? 是什么意思,它是用来检查 window 上是否已经存在事件监听器吗? - Shayan
这对我有用。谢天谢地。请注意,您需要有一个可调用的函数;-) 我把它放在<head>中。 - Adal

8

如果您的window.onload没有触发,本答案适用于您。

我发现以下内容可以解决该问题:

window.onload = myInitFunction;

或者
window.addEventListener("load", myInitFunction);

在这种情况下,被引用的函数(在本例中是myInitFunction)必须位于与onload事件所在的<script>-元素相同的位置(或被定义在之前的<script>-元素中)。否则它将无法工作。

因此,以下代码将不起作用

<html>
  <head>
    <title>onload test</title>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">

    <script>
      window.addEventListener("load", myInitFunction)
    </script>

    <script>
      function myInitFunction() {
        alert('myInitFunction');
      }
    </script>

  </head>
  <body>
    onload test
  </body>
</html>

但这样有效:

<html>
  <head>
    <title>onload test</title>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">

    <script>
      function myInitFunction() {
        alert('myInitFunction');
      }
    </script>

    <script>
      window.addEventListener("load", myInitFunction)
    </script>

  </head>
  <body>
    onload test
  </body>
</html>

这个生效(因为我们只有一个<script>元素):

<html>
  <head>
    <title>onload test</title>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">

    <script>
      window.addEventListener("load", myInitFunction)

      function myInitFunction() {
        alert('myInitFunction');
      }
    </script>

  </head>
  <body>
    onload test
  </body>
</html>

如果由于某种原因您有两个 <script> 元素,无法(或不想)将它们合并,并且您希望 onload 定义在较高位置(即在第一个元素中),那么您可以通过以下方式解决:
而不是编写
window.onload = myInitFunction;

你写

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

或者,不必写成

window.addEventListener("load", myInitFunction);

你写

window.addEventListener("load", function() { myInitFunction() }); 

解决这个问题的另一种方法是使用旧的方式。

<body onload="myInitFunction()">

6

将window.onload行移动到javascript文件的末尾或初始函数之后,它就会起作用:

function resize(){
    heightWithoutHeader = (window.innerHeight - 85) + "px"; 
    document.getElementById("main-table").style.height = heightWithoutHeader;
    document.getElementById("navigation").style.height = heightWithoutHeader;
}
// ...
// at the end of the file...
window.onload = resize;
window.onresize = resize;

但是最好的做法是不要替换 onload。相反,将您的函数附加到 onload 事件上:
function resize(){
    heightWithoutHeader = (window.innerHeight - 85) + "px"; 
    document.getElementById("main-table").style.height = heightWithoutHeader;
    document.getElementById("navigation").style.height = heightWithoutHeader;
}
// ...
// at the end of the file...
window.addEventListener ? 
    window.addEventListener("load",resize,false) 
    : 
    window.attachEvent && window.attachEvent("onload",resize);

这对我有用,抱歉我的英语不好。


谢谢你,你救了我的一天,这对我也有效。 - Burhan Ul Haqq Zahir

3

在我编写的<script type="text/javascript">标签中,window.onload没有起作用。

相反,需要将其写入<script language="Javascript" type="text/javascript">标签中,这样它才能正常工作。


2
在我的情况下
window.addEventListener("load", function() {
    myDropdownFunction();
});

意外的是(对我来说),并没有帮助(我试图在用户使用浏览器后退按钮时设置下拉列表的值)。而window.onload由于Nick Craver♦在此之前解释的原因被<body onload="...">覆盖,因此无法正常工作。
所以我尝试使用jQuery,它像魔法一样奏效:
$(window).on('pageshow', function() {
    alert("I'm happy");
});

1

这对我有用,我认为你的问题出在其他地方:

 function resize(){
  var tester = document.getElementById("tester"),
      html = tester.innerHTML

  tester.innerHTML = html + "resize <br />"
 }  

window.onload = resize;
window.onresize = resize;

你可以在这里自行测试: http://jsfiddle.net/Dzpeg/2/

你确定它是唯一被调用的 onLoad 事件吗?也许其他 onLoad 事件会产生冲突。


0

以防有人觉得有用,我调用了两次函数,而不是一次:

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

0

在我的情况下,将目标参数设置为"_blank"已经解决了问题。

let wind    = open(url,"_blank","options here")
wind.onload = .... // works fine now


0
在我的情况下,问题是我的脚本被另一个动态加载(例如:使用$.getScript()),并且当它运行时,窗口的“load”事件已经触发。
我的解决方案:
  if (
    document.readyState === "complete" ||
    document.readyState === "interactive"
  ) {
    // load event already fired, this may happen if this script is loaded dynamically.
    // Run immediately.
    execOnLoad();
  } else {
    // SEE: https://dev59.com/AnE85IYBdhLWcg3wXCW1
    window.addEventListener
      ? window.addEventListener("load", execOnLoad, false)
      : window.attachEvent && window.attachEvent("onload", execOnLoad);
  }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接