Where to put event handlers for document elements

Hello

I have the following code from a tutorial I am working through

        window.onload = function() {
        canvas=document.getElementById("gameCanvas");
        canvasContext=canvas.getContext('2d');  
        var framesPerSecond = 35;
        setInterval(updateAll, 1000/framesPerSecond);
               
        canvas.addEventListener('mousemove', updateMousePos);
       
         carPic.src = "player1car.png"; // when loaded this will call the onload function  
          carReset();
          };
          

        //evnt handlers
        
         carPic.onload = function() {
             carPicLoaded = true;
         }

Open in new window


In the tutorial the onload function for the carPic is inside the window.onload function. I have moved it outside for clarity and it still works but I do not know if this will cause me problems later down the line.

1)Should i have left it in the windows.onload function or can it go anywhere?
2)Is there a convention for where you put event handlers in Javascript? In other languages I usually write them at the top.
3) If there is a convention I presume there is a reason behind it. If there is a reason why event handlers should be written in a certain way (for example, they may need to be coded in a certain way for use with Ajax), please could you give a brief pointer as to why and I can look into it further

Thanks
Andrea EdwardsAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

zephyr_hex (Megan)DeveloperCommented:
If it's interacting with elements on the page, it should go in windows.onload.  Otherwise, you risk the code running before the page has loaded (which means it may not give you the results you expect).  Code inside of windows.onload will not run until the page elements have loaded.

There are two main conventions for where to place JS (event handlers or otherwise).  Top of HTML and Bottom of HTML.

The theory behind placing JS at the bottom of your page is that the browser will render the page to the user faster.  This comes into play when the browser encounters scripts because it will start to download those scripts.  If your link to .js is at the bottom of the page, all of your HTML has rendered and given the user something to see before the .js starts to download.  If your .js is linked at the bottom, then your JS code must come after that link, so it, too, would go at the bottom.

But, some people still put JS at the top.  I often do this because I prefer seeing JS code before I see the HTML, and there's no humanly noticeable difference in load time in these cases.  There are pages out there where it does make a humanly noticeable difference.

So, the answer to where to place JS is that it depends.  The most important factor would be performance.  If performance is not an issue, it is more a matter of developer preference.
0
Andrea EdwardsAuthor Commented:
Thank you for your detailed answer which makes sense. A couple of tiny questions:

1) the code to create the image is after my variable declarations, before the windows.onload

carpic = document.createElement("img")

Open in new window


and then carPic.src function call and its onload function are inside windows onload. The tutorial says it is the carPic.src function that triggers the onload function and not the createElement? This page also  seems to suggest it is when the image is downloaded that the onload event handler is called

http://blog.teamtreehouse.com/learn-asynchronous-image-loading-javascript

I can't find out if createElement could call the onload event handler if it could see it (e.g. if it was outside the windows.onload). It would make sense to me that creating the element does not trigger the onload, rather downloading its image triggers it. I will test this when I get access to my development machine. I might be being stupid (probably) but I cant find a javascript api which tells me the event handlers a function call triggers. If there is one, please can you point me to it. I have a very old oreilly javascript book with function calls but that only gives arguments and return values, not events triggered

2)in the window.onload, are either of the following preferable?

  carPic.src = "player1car.png"; 
  
 carPic.onload = function() {
             carPicLoaded = true;
         }
      

Open in new window

         

or
       
 
  

 carPic.onload = function() {
             carPicLoaded = true;
         }
carPic.src = "player1car.png"; 
  
  

Open in new window

 


I may well have a separate question on how javascript finds its event handlers :) but for now I would just like to now which of the above is preferable coding style.

Many thanks
0
Andrea EdwardsAuthor Commented:
For example I have found this
https://developer.mozilla.org/en-US/docs/Web/API/Document/createElement
https://dom.spec.whatwg.org/#dom-document-createelement

but they dont say what events are triggered

This also doesnt say setting the src triggers an onload

https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement/src

Thanks
0
Ultimate Tool Kit for Technology Solution Provider

Broken down into practical pointers and step-by-step instructions, the IT Service Excellence Tool Kit delivers expert advice for technology solution providers. Get your free copy now.

zephyr_hex (Megan)DeveloperCommented:
1)  There is only one function in the code you posted.  This is just an assignment: carPic.src = "player1car.png";

You said:
The tutorial says it is the carPic.src function that triggers the onload function and not the createElement?

But, that tutorial says,
Once you set the src attribute on this image downloading will start, so before that we want to create a handler for the onload event. Once the image has been downloaded this will trigger.

The tutorial doesn't say that setting the src attribute on carPic triggers the carPic.onload function.  And it doesn't.  What triggers the carPic.onload function is when that element (the img tag itself) is loaded on the page.  The img tag can fully load with or without the src attribute.   And this leads to your second question

2)  What is preferable depends on what you intend carPicLoaded = true; to mean.  If you intend it to mean that the img tag itself has fully loaded to the DOM, then you second code example is more accurate:

carPic.onload = function() {
             carPicLoaded = true;
         }
carPic.src = "player1car.png"; 

Open in new window


If carPicLoaded = true; means that the PICTURE referred to by the src attribute has loaded, then... well, then neither or your examples is right.  JavaScript will set the src attribute on the img tag, and start to download the image, but it will not wait for that image to load before moving on to set carPicLoaded = true;
This is for two reasons.  First, JavaScript doesn't wait to execute the next line of code.  Second, carPic.onload is true as soon as the img tag loads to the DOM (regardless of whether or not the src attribute is set).

If you want to wait and set carPicLoaded = true; when the img WITH the src attribute is loaded, then you need to add the src attribute to the img tag before the img tag is get loaded to the page.  There are several ways to do that, and there really is no convention regarding which way to do it.  Personally, I would create the img tag, add the src attribute, and then add the img tag to the page.  Then, it doesn't matter whether creating the img tag (with the src attribute) is done inside or outside windows.onload.  carPic.onload will not run until the img tag is loaded on the page, so as long as that src attribute is added to the img tag before the tag is added to the page, carPic.onload will not set carPicLoaded = true; until the picture itself has loaded.

Hopefully that makes sense.
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
Andrea EdwardsAuthor Commented:
Hi

Thanks for your reply. please could you advise what triggers the onload event for the carPic. You said 'What triggers the carPic.onload function is when that element (the img tag itself) is loaded on the page' .' so I am guessing it is the completion of this code

carpic = document.createElement("img")

Open in new window


Im not sure yet from the tutorial  whether the carPic loaded = true means the img element has loaded or whether its src has loaded . I'm presuming it is the first case. You said this is preferable to make sure the DOM has loaded the img (the first case)

carPic.onload = function() {
             carPicLoaded = true;
         }
carPic.src = "player1car.png";

Open in new window


This will set the src attribute on the img tag, and start to download the image, but it will not wait for that image to load before moving on to set carPicLoaded = true. That's fair enough I think.

I'm not sure how javascript manages events (and I dont want to get into detail) but if it is interpreted, is it correct that the window.onload will run in a procedural fashion meaning it will go through the code line by line until it gets to the event handler. It 'knows' the img element  is loaded and so  triggers the event handler. If this is correct, will it run the event handler in the same thread/process so the event handler is finished before you move on to setting the src or will it set the event handler off in a separate thread aysnchronously so while that is going on in the background the current 'thread' will move on to the next line of code which is setting the img src. You said javascript doesnt 'wait to execute the next line of code' so I'm guessing event handlers and image downloading and things like that are done 'in the background' while javascript moves on to the next line of code. In summary it will 'see' the event handler and know needs to be called, it will manage that in the background, and then move on to the next line of code setting the src. If this isn't correct, however, I dont know why the onload event handler has to be inside the window.onload for it not to be called until the whole page has loaded. This requirement suggests the event handler doesn't get 'seen'  until you reach the window.onload function and that when it sees the event handler, JS checks if its necessary conditions are met and triggers it. This also suggests the event handler doesnt get seen until you reach it at its position in the code

If the above is all correct I am guessing the tutorial it isn't bothered that the image src has downloaded as download speeds are fast; the code just wants to be sure the image element has been loaded by the DOM and can be used in the code and the image src will download asyncronously in the background

Can I just confirm that if the img onload event handler was not inside window.onload then this event handler could be called when the img element has loaded but necessarily when the rest of the page has loaded so you may get unexpected results. If my other comment was correct, JS will see the event handler when it gets to it in its procedural path through the code

Sorry for repetition but I am going to print this comment so i'm putting anything germane in it

Many thanks
0
Andrea EdwardsAuthor Commented:
Thank you for your clear explanation
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
JavaScript

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.