onload function init not found - javascript

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);
}

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].

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.

Related

addEventListener on a body element does not get executed

I am using MS Edge in IE11 compatibility mode and have an HTML page in which I have:
<input id="onLoadAttributeHiddenId" type="hidden" value="schadenAuswahl.setCustomCheck();schadenAuswahl.createArrays();">
Further below, I have also:
<script language="JavaScript1.1" src="../js/table_head_uip.js"></script>
And in the table_head_uip.js, I have:
document.body.addEventListener('load', customOnLoadFunction, false);
function customOnLoadFunction(){
var onLoadAttributeFunctStr = document.getElementById("onLoadAttributeHiddenId").value;
var onLoadAttributeFunct = new Function(onLoadAttributeFunctStr);
onLoadAttributeFunct;
}
Now, when I put breakpoints in the table_head_uip.js, the line.
var onLoadFunct = document.body.addEventListener('load', customOnLoadFunction, false);
It gets executed, but the function customOnLoadFunction never gets completed. Also, I do not receive any errors in the console.
Any help will be appreciated.
load events only fire on elements which load things (like an <img> with a src attribute) and the window object (for when the entire document, including its dependencies, has loaded).
The body element doesn't load anything.
The equivalent of the obsolete onload attribute for the body is a load event that fires on the window object. That attribute only existed because, since window isn't an element, you couldn't put attributes on it.
Additionally, the statement onLoadAttributeFunct doesn't do anything. To be useful you need to, for example, put () after it to call it.
new Function(onLoadAttributeFunctStr) is effectively a time delayed eval and is considered dangerous, slow, and hard to debug. You should reconsider the design of your application if you need that.

Remove Attribute-defined `onload` from `<body>`

I've been working on this for a few hours and am at the point where I feel like I might be trying to accomplish something unworkable. Any advice or insight is definitely appreciated!
The use case I'm targeting requires interrupting the browser's DOM parsing before it has a chance to draw the <body> element. To accomplish this, I've used this one-liner as the first script called in my <head> element:
document.replaceChild(document.createElement('html'), document.children[0]);
This successfully prevents the browser from calling any subsequent scripts, and the <body> element remains un-rendered. However, if the markup includes an onload attribute on the <body> element, that function or code is still called by the browser.
As the context which intercepts DOM parsing is in <head>, I can't use document.body.removeEventListener() to drop the event listener, because the body element doesn't exist yet. Setting window.onload to null has no effect, and neither does trying to intercept setting of window.onload using Object.defineProperty(window, 'onload', {...}). In each case, the onload function or statements still get called.
To preempt the obvious question as to why I can't just avoid using <body onload="...">, the use case is for developer tooling, so I'm trying to create contingency for certain absolute conditions. If it can't be done, it isn't killer to my project, but I'd sure like to know why it can't be done.
Thanks in advance!
You can use Document readystate at the interactive state, and overwrite the onload attribute.
document.onreadystatechange = () => {
if (document.readyState === 'interactive')
window.onload = null;
}
(Added your code from your comment for completeness.)

HTML Image onload triggers onerror?

I have an html image that is labeled as follow
<image src = 'image.png' onerror = "handleError(this)" onload = "handleLoad(this)">
function handleError(n){
getFirstChild(n.parentNode).style.display = '',n.style.display = 'none';
}
function handleLoad(n){
getFirstChild(n.parentNode).style.display = 'none',n.style.display = '';
}
I have a separate function getFirstChild but that doesn't have anything to do with the following problem.
Basically what is happening is in IE 11 is that the onLoad handler is getting fired and my function is setting the displays correctly, however right after the onload is fired, the onerror is also fired and overwrites what the handleLoad function has done.
Sadly this application is only supported in the IE browser but its only happening in IE11 version, in IE10 this works as expected.
I'm not sure how an onLoad can trigger, and then the onError be trigger right after when the onLoad has found the image from the src.
SECOND EDIT
As the comment below shot I'm not able to reproduce this in a jfiddle on IE11. This could be because of different things my code is trying to do at the same time, but is there any way to see why the onerror handler was trigger? I tried printing out the src of the Image item but that doesn't seem to be the issue as both onError and onLoad return the same src, and the image is clearly there.
Anyway that i can see what is causing the onError to trigger?
The window.onload event is used by programmers to kick-start their web applications.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();
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
};
as we can see there are many problems associated with using DOM event handler in IE, hence conditional compilation can be one more option for OP's problem.
IMHO you should go for this link:
http://dean.edwards.name/weblog/2005/09/busted/

Javascript not finding Button with ID

In my HTML, I have a simple button defined, like so:
<button id="toggleButton">Stop</button>
I am trying to grab it with the following code:
buttonElement = document.getElementById("toggleButton");
with the goal of assigning an event to it, like so:
buttonElement.onclick = stopTextColor();
The problem is that the getElementById is returning null, even though I can see it in the DOM. What am I doing wrong here?
For clarity, I posted the full code at http://cdpn.io/sqEuH
The problem, probably, is that you're including the JS in the head. What's happening there is the JS is running before the page gets loaded, so the button doesn't show up. Move it to right before the </body> tag, and this problem will be solved, or wrap it with a window.onload() event.
The code you post will work unless the javascript cannot access the given DOM element.
The main possibilities:
The javascript runs before the DOM is parsed (IE if you run it in the head of the document without any code to instruct it to wait till the DOM is ready)
You can usually get around this by placing your script at the bottom of the body rather than in the head or midway through the body. The essential thing to understand here though is that JS can't access an element till the browser has parsed the DOM. The browser parses HTML top-down, and JS scripts run top down, so if you run the JS before the element is parsed, it won't be available to the javascript function yet.
The javascript runs in a context where it can't access the element (inside an iFrame for instance). In this case it would be a question of whether the element is really under the "document" object that you're referring to. If the element is inside an iFrame it will be underneath the iFrame's document object.
Try putting your script just before closing your <body> tag. The DOM is probably not fully loaded when your script is run.
Also, I think you have an error in your Javascript. It should be
buttonElement.onclick = stopTextColor;
instead of
buttonElement.onclick = stopTextColor();
Altough it shouldn't throw any error, it's good practice.
If you want to keep your Javascript before <body>, you can use a listener to wait for the DOM to be loaded and then execute your script, like this :
window.addEventListener("DOMContentLoaded", function() {
buttonElement = document.getElementById("toggleButton");
buttonElement.onclick = stopTextColor;
}, false);
[edit]
The snippet above doesn't work in IE < 9. If you need to support it, use document.load instead, it should give the same result, like so :
document.onload = function() {
buttonElement = document.getElementById("toggleButton");
buttonElement.onclick = stopTextColor;
}
The differece between both, besides browser compatibility, is that window.addEventListener("DOMContentLoaded", function() {...} will fire when the DOM is loaded, but window.load will fire when the DOM AND all other resources (images, stylesheets, etc.) are loaded (slower, and not necessary in your case).

Javascript: Best place to register event handlers

This question is so basic, I'm certain in must be a duplicate of something, even though I've looked for something similar.
My question is basically: Where is the best place to initially register event handlers for HTML elements?
The easiest way to register an event handler is obviously to just do it inline:
<div id = "mybutton" onclick = "doSomething()">Click me</div>
But this goes against the overwhelming march towards separation of logic and content in modern web development. So, in 2012, all logic/behavior is supposed to be done in pure Javascript code. That's great, and it leads to more maintainable code. But you still need some initial hook that hooks up your HTML elements with your Javascript code.
Usually, I just do something like:
<body onload = "registerAllEventHandlers()">
But... that's still "cheating", isn't it - because we're still using inline Javascript here. But what other options do we have? We can't do it in a <script> tag in the <head> section, because at that point we can't access the DOM since the page hasn't loaded yet:
<head>
<script type = "text/javascript">
var myButton = document.getElementById("mybutton"); // myButton is null!
</script>
</head>
Do we place a <script> tag at the bottom of the page or something? Like:
<html>
<body>
...
...
<script type = "text/javascript">
registerAllEventHandlers();
</script>
</body>
</html>
What is the best practice here?
You can use window.onload:
<script type = "text/javascript">
window.onload = registerAllEventHandlers;
</script>
Or if you use jquery:
$(registerAllEventHandlers);
Using onload works because it registers onload event immediately but fires it when DOM is ready.
I had a similar answer to this but was about JavaScript in general. But the idea is still the same - load scripts before closing the body.
Take advantage of libraries that abstract the window.onload and the DOM ready event. That way, you can load the scripts as soon as the DOM is ready.
Personally, I have no problems with adding onlclick="doSomething();" to elements. No logic, just a function call.
All logic is where it should be: in the function defined in the HEAD or a separate file.
Tell me what the difference is when you add href="somepage.html" or even href="somepage.html#someanchor" to an A tag.
You should register your event handlers as soon as the DOM is ready. Detecting this across all browsers hasn't always been easy, although with the notable exception of IE 8 (and earlier) most widely used browsers now support the DOMContentLoaded event (thanks to gengkev for pointing that out in the comments).
This is essentially equivalent to calling your registerAllEventHandlers function at the end of your body, but it has the advantage that you don't need to add any JavaScript to your HTML.
It is significantly better than using window.onload because that isn't executed until all of the page's assets (images, CSS etc.) have loaded.
If you're using one of the major JavaScript frameworks, then you can very easily detect when the DOM is ready, even in older versions of IE. With jQuery you would use the ready event:
jQuery(document).ready(function () {
// Your initialisation code here
});
Or the shorthand:
jQuery(function() { … });
With Prototype you would use the dom:loaded event:
document.observe("dom:loaded", function() {
// Your initialisation code here
});

Categories

Resources