【问题标题】:window.onload event doesn't fires or "how to properly initialize js project?"window.onload 事件不会触发或“如何正确初始化 js 项目?”
【发布时间】:2013-10-15 23:51:54
【问题描述】:

这个问题似乎很常见,虽然我找不到答案。

我有这个带有唯一画布标签的简单 html

<!doctype html>

  <head>
    <meta charset = "utf-8">
    <script src="js/script.js"></script>
    <title>Title</title>
  </head>

  <body>
    <canvas id = "canvas"></canvas>  
  </body>

</html>

在 script.js 中,我试图捕捉 window.onload 事件:

window.onload = init;

function init(){
  var canvas = document.getElementById("canvas");
  var context = canvas.getContext("2d");

  context.fillRect(50, 20, 150, 150);
}

但是什么也没发生。我假设甚至在执行第一行 js 之前就加载了 html。

所以我发现 onload 事件的替代方法是将脚本定义放在正文的末尾,因此在执行脚本时应该已经加载了窗口。所以我这样做了:

<!doctype html>

  <head>
    <meta charset = "utf-8">   
                                  <!-- gone -->
    <title>Title</title>
  </head>

  <body>
    <canvas id = "canvas"></canvas> 
    <script src="js/script.js"></script>  <!-- inserted -->
  </body>

</html>

<!-- window.onload = init; -->
init()                              <!-- inserted -->

function init(){
  var canvas = document.getElementById("canvas");
  var context = canvas.getContext("2d");

  context.fillRect(50, 20, 150, 150);
}

在某种程度上它可以工作(绘制矩形),但给我一个错误Uncaught ReferenceError: context is not defined

所以我的问题是我做错了什么?我也想知道是否有更好的方法来做到这一点。

附:我倾向于不使用 jquery...

已编辑:上下文错误与上面的代码无关,尽管我仍然不喜欢将 js 文件的链接放在正文末尾的想法...

【问题讨论】:

  • 您在第一次尝试 init() 时缺少函数调用;以及第二次尝试在同一行“init();”的冒号。
  • 不,在第一个例子中我不需要调用它。
  • @Casey:顺便说一句,我从不记下试图帮助我的人的问题,即使答案显然是错误的。应该是比你我更懂html/js的人吧。
  • 有道理,很好听。很多人都是为了状态/分数,而不是堆栈背后的想法。只是想确定一下。

标签: javascript html


【解决方案1】:

在这里,试试下面的代码。重点是:

(1) 您可以指定多个函数在 onload 事件触发时运行。 (2) 您可以将它们附加到任何您喜欢的位置。当附加事件触发时,它们仍然会被调用。但是 - 我认为不能保证函数将以与它们附加的顺序相同的顺序执行。使用 addEventListener 将多个函数附加到单个事件时请记住这一点。

总之,输出是:

created with function called from **test.js**
created with function called from test.html
created with function called from **test.js**

test.html

<!doctype html>
<html>
<head>
<script src='test.js'></script>
<script>
window.addEventListener('load', mInlineJsLoadFunc, false);
function mInlineJsLoadFunc()
{
    var div = document.createElement('div');
    div.appendChild( document.createTextNode('created with function called from test.html') );
    document.body.appendChild(div);
}
</script>
<style>
</style>
</head>
<body>
</body>
<script src='test.js'></script>
<html>

test.js

window.addEventListener('load', mExternalJsLoadFunc, false);
function mExternalJsLoadFunc()
{
    var div = document.createElement('div');
    div.appendChild( document.createTextNode('created with function called from **test.js**') );
    document.body.appendChild(div);
}

【讨论】:

  • addEventListener 似乎解决了这个问题。但是它与'window.onload = init'有什么不同呢?你会建议不要使用第二个吗?
  • 为什么还要输出三行呢? (我期待两个)
  • @msgmaxim - 首先,是的 - 我建议 not 使用 window.onload = init。其次,很简单,外部脚本被附加了两次——一次在文档头部,另一次在 正文之后。这占了第 1 行和第 3 行。第 2 行当然来自 html 文件中的脚本。
【解决方案2】:

我看不出它不应该工作的原因,例如这是带有警报的simple jsfiddle onload

虽然你不需要分两步做,你可以写

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

如果这在您的情况下不起作用,那么调试或登录到控制台window.onload 的值是什么,可能是其他一些库正在覆盖它,这就是为什么最好使用像 jQuery 这样的库

【讨论】:

  • 我不知道,由于某种原因,它在 jsfiddle 上运行良好,在我的机器上运行不正常。 window.onload 的值正是我分配给它的函数,但它无论如何都不会触发。无论如何,正如@enhzflep 提到的 window.addEventListener 似乎可以解决问题,所以我试图找出原因。
  • 它在 jsfiddle 而不是在他的代码中工作的原因是 jsfiddle 在页面加载后调用脚本。通过在 header 中包含他的脚本,他得到了一个空值 var canvas = document.getElementById("canvas");因为该 ID 尚不存在。如果他采用相同的脚本并像@enhzflep 在 html 的最后几行中那样加载它,一切都会好起来的。尽管将函数附加到 onload 事件的要点肯定是更好的做法。
【解决方案3】:

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

function yourFunction(){
    // ...
}
// ...
// at the end of the file...
window.onload = yourFunction;
window.onresize = yourFunction;

但最好不要更换 onload。而是将您的函数附加到 onload 事件:

function yourFunction(){
    //...
}
// ...
// at the end of the file...
window.addEventListener ? 
    window.addEventListener("load",yourFunction,false) 
    : 
    window.attachEvent && window.attachEvent("onload",yourFunction);

这对我有用,对不起我的英语。

【讨论】:

  • 这对我来说效果很好。谢谢。
猜你喜欢
  • 1970-01-01
  • 2017-08-19
  • 2013-05-20
  • 1970-01-01
  • 1970-01-01
  • 2020-01-29
  • 1970-01-01
  • 1970-01-01
  • 2013-10-24
相关资源
最近更新 更多