-1

I'm encountering a strange issue. I am developing a books application and using javascript onload. I read somewhere that its best to include your javascript at the end of the html. This works for most of the html loaded. However some complain that onload init() not found. This gets solved if i include the javascript in the html head. But than other htmls start behaving strangely. onload gets called before the page is fully loaded. i dont get the correct scroll width. Please suggest what could be worng. Whats the best way of including javascripts. Thanks

html is as follows

columizer id use css column-width which i've defined like this. css style below

#columnizer 
{
width:290px;
height:450px;
column-width:290px;
column-gap:10px;
word-wrap:break-word; 
}

Javascript onload is defined like this.

function init() 
{
docScrollWidth = document.getElementById('columnizer').scrollWidth;
document.getElementsByTagName('body')[0].style.width = docScrollWidth  + "px";
window.external.notify(str);
}
ashok
  • 187
  • 2
  • 11
  • 1
    You will have to show us your actual javascript and where it is in the page. That's the only way we can help. – jfriend00 Apr 12 '14 at 05:20
  • My guess is that you're doing something like `window.onload = init();` instead of `window.onload = init;` and the init function will have to be declared before you do that assignment. You assign function references without the parens. Using the parens causes it to get executed immediately. – jfriend00 Apr 12 '14 at 05:22
  • You might find this interesting reading [pure JavaScript equivalent to jQuery's $.ready() how to call a function when the page/dom is ready for it](http://stackoverflow.com/questions/9899372/pure-javascript-equivalent-to-jquerys-ready-how-to-call-a-function-when-the/9899701#9899701) – jfriend00 Apr 12 '14 at 05:29
  • I am using javascript like this. i have a javascript.js file in which i define the onload function like this. function init() { docScrollWidth =document.getElementsByTagName('body')[0].style.width ;window.external.notify(str);} Further i use it in my html as follows. – ashok Apr 12 '14 at 05:50
  • Multiline code in comments is simply not readable. Please use the edit link and add it to your question. – jfriend00 Apr 12 '14 at 05:59
  • using window.onload = init; resolved my issue. Thanks – ashok Apr 16 '14 at 05:32

2 Answers2

0

First, let me define the problem. The window.onload event is used by programmers to kick-start their web applications. This could be something trivial like animating a menu or something complex like initialising a mail application. The problem is that the onload event fires after all page content has loaded (including images and other binary content). If your page includes lots of images then you may see a noticeable lag before the page becomes active. What we want is a way to determine when the DOM has fully loaded without waiting for all those pesky images to load also.

Mozilla provides an (undocumented) event tailor-made for this: DOMContentLoaded. The following code will do exactly what we want on Mozilla platforms:

// for Mozilla browsers

if (document.addEventListener) {
  document.addEventListener("DOMContentLoaded", init, false);
}

So what about Internet Explorer?

IE supports a very handy (but non-standard) attribute for the tag: defer. The presence of this attribute will instruct IE to defer the loading of a script until after the DOM has loaded. This only works for external scripts however. Another important thing to note is that this attribute cannot be set using script. That means you cannot create a script using DOM methods and set the defer attribute – it will be ignored.

Using the handy defer attribute we can create a mini-script that calls our onload handler:

<script defer src="ie_onload.js" type="text/javascript"></script>

The contents of this external script would be a single line of code to call our onload event handler:

init();

There is a small problem with this approach. Other browsers will ignore the defer attribute and load the script immediately. There are several ways round this. My preferred method is to use conditional comments to hide the deferred script from other browsers:

<!--[if IE]><script defer src="ie_onload.js"></script><![endif]-->

IE also supports conditional compilation. The following code is the JavaScript equivalent of the above HTML:

// for Internet Explorer

/*@cc_on @*/
/*@if (@_win32)
  document.write("<script defer src=ie_onload.js><\/script>");
/*@end @*/

So far so good? We now need to support the remaining browsers. We have only one choice – the standard window.onload event:

// for other browsers

window.onload = init;

There is one remaining problem (who said this would be easy?). Because we are trapping the onload event for the remaining browsers we will be calling the init function twice for IE and Mozilla. To get around this we should flag the function so that it is executed only once. So our init method will look something like this:

function init() {
  // quit if this function has already been called
  if (arguments.callee.done) return;

  // flag this function so we don't do the same thing twice
  arguments.callee.done = true;

  // do stuff
};

I’ve provided a sample page that demonstrates this technique.

Anant Dabhi
  • 10,864
  • 3
  • 31
  • 49
  • Is this a wild guess for how much of this is relevant to the OP's code since we have very little actual info on what their problem is? The `load` event will work just fine for simple things if implemented properly as will just simply placing the code at end of the `` after the HTML. – jfriend00 Apr 12 '14 at 05:26
0

Since the actual answer was in my comment, I'll add that to my answer:

My guess is that you're doing something like window.onload = init(); instead of window.onload = init; and the init function will have to be declared before you do that assignment. You assign function references without the parens. Using the parens causes it to get executed immediately.


You say you're using this code:

 docScrollWidth = document.getElementsByTagName('body')[0].style.width 

The main problem with this is that style.width ONLY reads a style attribute set directly on the body object. It doesn't get the width of the object as calculated by layout or CSS rules.


So, what you should use instead really depends upon what you're trying to do. The body width will nearly always be the same or more than the window width unless your content is entirely fixed width. So, that makes me wonder what you're trying to accomplish here? What you should use instead depends upon what you're really trying to do.


FYI, document.body is a direct reference to the body object so you don't need document.getElementsByTagName('body')[0].

jfriend00
  • 683,504
  • 96
  • 985
  • 979
  • i am using css column-width property and this is why i assigned id to body. Also i have a css file the defines columnizer like this. #columnizer { width:290px; height:450px; column-width:290px; column-gap:10px; word-wrap:break-word; } – ashok Apr 12 '14 at 06:06
  • @ashok - this is kind of a waste of your time here until you show us the actual code you're using including relevant CSS and then describe what you're really trying to accomplish. Theoretical questions are very difficult to get relevant answers to. Specific questions with your actual code are easy to answer. – jfriend00 Apr 12 '14 at 06:07
  • @ashok - Copied my comment into my answer which turned out to be your issue. – jfriend00 Apr 16 '14 at 05:35