8

This problem seems to be common, though I couldn't find the answer.

I've got this simple html with the only canvas tag

<!doctype html>

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

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

</html>

and in script.js I'm trying to catch window.onload event:

window.onload = init;

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

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

But nothing happens. I assume that the html is loaded even before the first line of js executed.

So I found that the alternative to onload event would be to put script definition in the end of the body, so when script being executed the window is supposed to be loaded alreade. So I did like this:

<!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>

and

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

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

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

And in a way it works (draws rectangle) , but gives me an error Uncaught ReferenceError: context is not defined.

So my question is what I'm doing wrong? I'm also wonderring if there is a better way to do this.

P.S. I tend not to use jquery...

EDITED: the error with context has nothing to do with the code above, although I still don't like the idea of putting the link to js file in the end of the body...

msgmaxim
  • 748
  • 2
  • 8
  • 15
  • You are missing the function call on first attempt init(); and the colons on second attempt at same line "init();". – Casey Oct 15 '13 at 23:57
  • No, in the first example I dont need to call it. – msgmaxim Oct 16 '13 at 00:26
  • @Casey: btw I never mark down the question of someone who is trying to help me, even if the answer is clearly wrong. It was probably someone who understands html/js better than you and me. – msgmaxim Oct 16 '13 at 00:32
  • 1
    Makes sense, and good to hear. So many people are here for the status/score, more than the idea behind stack. Just wanted to make sure. – Casey Oct 16 '13 at 01:25

3 Answers3

7

Here, try the following code. The key points being:

(1) You can assign more than 1 function to be run when the onload event fires. (2) You can attach them whereever you please. They all still get called when the attached event fires. However - I don't think there is a guarantee that functions will be executed in the same order that they were attached. Keep this in mind when attaching multiple functions to a single event using addEventListener.

Anyhow, the output is:

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);
}
enhzflep
  • 12,142
  • 2
  • 26
  • 47
  • addEventListener seem to solve the issue. But how is it different from 'window.onload = init'? Would you recommend not to use the second? – msgmaxim Oct 16 '13 at 00:50
  • And why three lines of output anyway? (I'm expecting two) – msgmaxim Oct 16 '13 at 00:51
  • 1
    @msgmaxim - Firstly, Yes - I would reccomend _not_ to use `window.onload = init`. Secondly, simple, the external script is attached twice - once in the document head, and again _after_ the body. That accounts for line #1 and line #3. line #2 of course comes from the script in the html file. – enhzflep Oct 16 '13 at 00:57
4

I don't see a reason why it should not work e.g. here is a simple jsfiddle onload with alert

Though you don't need to do it in two steps and you can just write

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

If this is not working in your case then debug or log to console what is the value of window.onload, may be some other library is overriding it, that is why it is better to use some library like jQuery

Anurag Uniyal
  • 77,208
  • 39
  • 164
  • 212
  • I don't know, for some reason it works fine on jsfiddle and doesn't work on mine machine. The value of window.onload is exactly the function I assign to it, but it doesn't fire anyway. Anyway, as @enhzflep mentioned window.addEventListener seem to do the trick, so I'm trying to find out why. – msgmaxim Oct 16 '13 at 00:57
  • The reason it works in jsfiddle and not in his code is that jsfiddle is calling the script AFTER page load. By including his script in the header , he's getting a null value for var canvas = document.getElementById("canvas"); as that ID does not yet exist. Were he to take the same script and load it as @enhzflep does in the final lines of the html, all would be well. Though the points about attaching the function to the onload event are definitely better practice. – brianfit Sep 27 '19 at 07:13
3

Move the window.onload line to the end of the javascript file or after the initial function and it will work:

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

But it's a best practice if you don't replace the onload too. Instead attach your function to the onload event:

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

That worked for me and sorry for my english.

august0490
  • 471
  • 7
  • 9