0

My java script file is referenced in the body of my base template:

<body>
...
<script type="text/javascript" src="/static/js/test.js"></script>
</body>

I an another template which extends the base template, the java script function draw() defined in test.js can be invoked by using the onclick Event. Sadly I only get a picture when clicking over the canvas area. But invoking the function by <script> draw(); </script> occurs the following error: ReferenceError: draw is not defined How can this possibly be?

...  
<div class="panel-body">
  # works perfectly fine, somehow the function can be accessed
  <canvas id="canvas" onclick="draw()" width="300" height="10"></canvas>
  # occurs an error, somehow the function can't be accessed anymore...
  <script> draw(); </script>
</div>
...

I use python flask framework for back end programming.

davidism
  • 121,510
  • 29
  • 395
  • 339
ericMTR
  • 211
  • 3
  • 14

3 Answers3

1

Because you initialized the <script> at the end of the webpage, and you call draw() before it's initialized.

I would put it in the head tag:

<head>
    ...
    <script type="text/javascript" src="/static/js/test.js"></script>
</head>

You said that for the onclick it works, of course it works, when you click on the canvas the draw() function is already initialized.

Mingle Li
  • 1,322
  • 1
  • 15
  • 39
1

The order of the script is what matters here. Scripts are loaded in the order encountered in the page.

Since "draw()" is a direct call, I presume this is defined before the tag in the body, so this why the browser says it is not defined. On the other hand, the onClick of the canvas can happen only after the page is loaded, so that's why it is working there.

I recommend to put the javascripts of a specific page below the scripts of the base template somehow (you have to use maybe you'll need two separate references for that), or you can use other techniques like JQuery's $(document).ready().

Here is a very similar question, hope that helps: load and execute order of scripts

Community
  • 1
  • 1
gabowsky
  • 572
  • 4
  • 13
1

Why won't you wait for the document to load? That would be the proper solution to this problem.

document.addEventListener('load',  function (){
    draw();
});

Sorry about the ugly indentation, I'm using my phone

Yehonatan
  • 3,168
  • 7
  • 31
  • 39
  • @ Yehonatan Well this works only for the template with the defined canvas in it. all other templates get following error: `TypeError: Cannot read property 'getContext' of null` – ericMTR Sep 12 '15 at 15:48
  • Well, I haven't seen you draw code but I'm pretty sure that you've done some getElementById and for that you need the element to exist. – Yehonatan Sep 12 '15 at 16:14