JavaScript onload function call suddenly produces "Object expected" - javascript

The following onload function call was working:
<script type="text/javascript">
function frameloaded() {
if (parent.leftframe) {
parent.leftframe.reportRightFrameReloaded();
}
}
</script>
</head>
<body onload="frameloaded();">
.... etc.
until I added an external javascript reference
<script type="text/javascript" src="sorttable.js"></script<
immediately before it. Then suddenly it started giving me "Object expected" in IE (I have IE8) and simply stopped working in Firefox (3.6.3). I figured there was a duplicate function name in the included file, so I gave it a random name and it still failed. I tried using
onload="this.frameloaded();"
and
onload="document.frameloaded();"
with no luck.
I tried moving my function above the included statement, but just got an empty frame.
Any ideas?
Thanks!

#Hamish was right. The problem was in sorttable.js. It uses window.onload, which conflicted with my BODY onload. In sorttable.js, there were several window.onload statements within some elaborate logic, so I couldn't just use the recommended solution in such cases, which would be to trigger all the required onload functions in the BODY onload event.
Instead, my solution, which I am not entirely comfortable with, is to put the contents of my frameloaded() method at the bottom of the BODY, but not inside a function. This way it executes as late as possible during the load process. This works (i.e. it runs after the tables that have to be loaded first have been loaded) in IE and Safari, but I am having trouble with the other browsers.

Related

IE8 seems to execute js before css is rendered

I've got a weird problem. I'm using Bootstrap for a website that has to be optimized for IE8. When i test the html prototype in a real IE8 (no IE emulation) the javascript seems to be executed before the website is rendered.
To prevent this I placed the javascript at the bottom of the body and the script is surrounded by a window load function.
Do i miss something? I don't want to use a SetTimeout.
A short js code example.
$(window).load(function() {
// for example a function that resets the sliders offset
function reset_slider() {
$('.slider-main').css({'margin-top': '0px'});
}
reset_slider();
}
All Browsers beside IE8 execute this script after the site is rendered.
Thanks in advance
Marcus
Set your js function to load after the page has.
window.onload = yourfunction
or you could use:
<body onload="yourfunction();">

Access HTML element later in document through JavaScript

I am just starting out with JavaScript and I have a simple code that sends a value to an element with id p. I am currently declaring this function in a <script> in the <head> element of my document.
function writeP(resultSet) {
document.getElementById('p').innerHTML = resultSet.length;
};
writeP(results);
When I have this listed within the <head> element and run the webpage, firebug throws this error at me: TypeError: document.getElementById(...) is null.
However, if I move the code block into a <script> tag beneath the element and then reload the webpage, no problems and the script works as it should. Is there any reason for this, and a way I could make this work so I wouldn't have to define my functions beneath the element or include a onload on my body element?
Thanks for your help
Reason is that by the time your launch js code, DOM is not yet prepared, and JS can't find such element in DOM.
You can use window.onload (docs on W3schools) trigger to fire your functions after all elements are ready. It's same as having onload property on body element, but is more clear, as you can define it in your js code, not in html.
JS evaluates syncronically. Therefore, it does matter WHEN you declare the function. In this case, you're declaring it before the element actually exists.
Second, when you declare a function with that syntax, it does get eval'd inmediately. If you declared, instead
var writeP=function(resultSet) {
document.getElementById('p').innerHTML = resultSet.length;
};
you could save just the call to the end of the Doc, and leave the declaration at the beggining.
However, I would advise you to read a few jQuery tutorials to learn easier ways to deal with dom manipulation. Nobody runs raw JS for that task anymore.
jQuery includes an useful call to document ready event, which will save you a lot of headaches and is -IMHO- more efficient than the onload event. In this case, you would include the jQuery library somewhere in your code
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
and then add
<script>
jQuery(document).ready(function() {
var writeP=function(resultSet) {
jQuery('#p').html(resultSet.length);
};
writeP(resultSet);
});
</script>
just about anywhere in your document or an external js file, as it suits you.

jQuery ready firing before custom behavior script initializes

Background
I've inherited an ancient web application that has input controls with custom behaviors defined with an old-fashioned HTC (HTML Component) script, e.g.:
<input name="txtFiscalYearEndDay" type="text" value="30"
maxlength="2" size="5" id="txtFiscalYearEndDay" class="Text1"
style="behavior:url(/path/js/InFocus.htc);" />
Here are the relevant parts of this HTC file to illustrate the issue:
<PUBLIC:COMPONENT tagName="InFocus">
<PUBLIC:METHOD NAME="setValid" />
<PUBLIC:ATTACH EVENT="ondocumentready" HANDLER="initialize" />
<SCRIPT LANGUAGE="javascript">
function initialize() {
// attaches events and adds CSS classes, nothing fancy
}
function setValid(bInternal) {
// checks some flags and changes a label
}
</SCRIPT>
</PUBLIC:COMPONENT>
So, nothing out of the ordinary so far. Additionally, I have some JS that runs on DOM-ready:
$(function() {
txtFiscalYearEndDay_Validate(document.getElementById('txtFiscalYearEndDay'));
});
And the validation function:
function txtFiscalYearEndDay_Validate(el) {
...
}
Note: I'm not using $('#txtFiscalYearEndDay') because then I really can't try to call setValid(true); on the element, nor do I want to have to do $('#txtFiscalYearEndDay')[0].setValid(true);.
The problem
At one point in the validation function, I'm attempting to call a method on the element, the one added by the HTC script:
el.setValid(true);
However, the IE debugger gets sad and complains that setValid() is not a function. Inspecting it in the debugger confirms this:
typeof el.setValid // "unknown"
Of course, once the page has completed rendering (or whatever period of time is needed for the document to actually be ready has passed), the validation function works as expected (because I'm calling the same validation function on change and blur events as well). That is, when the function is called outside of jQuery's on-DOM-ready function, it works just fine.
Do any of you have any ideas at to what might be happening here? Is jQuery's "ondomready" being registered before the HTC script's "ondomready"? Can I somehow change that order?
I'm currently seeing this behavior in all versions of IE.
EDIT: WORKAROUND
I discovered a workaround. If you take the function call out of the jQuery ready function and throw it at the end of the page, it works (i.e.:)
...
<script type="text/javascript">
txtFiscalYearEndDay_Validate(document.getElementById('txtFiscalYearEndDay'));
</script>
</body>
</html>
I do not know if HTC counts toward page ready but i suspect they do not.
What you might try is check something that only is tru after the HTC hase finished.
You own script should then start something like this:
function MyFunction() {
if(!HTCIsreadyTest()) {
setTimeout(MyFunction, 100);
return;
}
//the rest of your code
}
This basically makes you function check and restart in 100 milliseconds if conditions are not met untill the test succeds.
You could also ad a counter argument increasing it by one for each attempt to have some timeout code trigger if HTC sciprts has not loaded after 2 seconds
The easiest workaround I could find was to move the validation function call out of the jQuery ready() callback and move it to the end of the page:
...
<script type="text/javascript">
txtFiscalYearEndDay_Validate(document.getElementById('txtFiscalYearEndDay'));
</script>
</body>
</html>
However, I found a more elegant solution. Because I seemingly need to wait for all page resources to be loaded, I simply needed to move the function call out of the jQuery ready() callback and instead put it in a window load() callback:
$(window).load(function() { // instead of $(function() {
txtFiscalYearEndDay_Validate(document.getElementById('txtFiscalYearEndDay'));
});
I'm using the latter so I can keep all of the JS code together.

Jquery event handling code doesnt work after including script in head from an external js file

I included a script into my document's head that contains the following jquery code:
$('.unappreciatedIcon').click(function() {
alert('JS Works!');
});
In the body of my document I have following:-
<span class="unappreciatedIcon">.....</span>
But there is no alert displayed when I inserted the script into the document head from an external js file. When I had put this script in body simply below the target elements this worked flawlessly.
Thanks to you all:
I am getting this to work with the following code:
$(document).ready(function(){
$('.unappreciatedIcon').click(function() {
alert('fds');
})
});
Did you wrap your jquery in a $(document).ready(function() { // your code // }); ?
If not your jquery code is executing immediately and the browser has not loaded your span. You need to wait for the document to be ready (using the code above) before assigning events.
Update
$(document).ready(function() {
$('.unappreciatedIcon').click(function() {
alert('JS Works!');
});
});
When your script ran, it looked for an element having the class unappreciatedIcon. Nothing was found because the document is still being parsed and there was no node having the class unappreciatedIcon available in the document so far. The DOM is being constructed incrementally.
But when you put your script after the span element occurs, then $('.unappreciatedIcon') was found because it has been parsed and added to the DOM, so the click handler was tied to it.
Either run your code in a ready callback. The ready callback basically runs when the entire HTML has been parsed and the DOM is fully constructed which is usually a safe point to start running your JavaScript code that depends on the DOM.
$(document).ready(function() {
$('.unappreciatedIcon').click(...)
});
or put your code after the element occurs (don't need to wrap it inside the ready callback in this case),
<span class="someClass">..</span>
..
<script>
$('.unappreciatedIcon').click(...)
</script>
just going to go with basics but did you make sure to include the jquery library? If it doesn't work and it's in the code you can also open in firefox with firebug go to the console tab and see what error you have.
The javascript is being processed before the page has finished rendering. As Erik Philips suggested, you need to put this statement inside your $(document).ready() function to ensure the page is loaded before the statement is evaluated.
$(document).ready(function(){
$('.unappreciatedIcon').click(function() {
alert('JS Works!');
});
});
here is the fiddle http://jsfiddle.net/Pf4qp/
Since HTML loads from top to bottom, the head loads before the rest of the page. You could solve this problem by putting the link to your js file right before the end tag. However, its generally better practice to put the javascript link in the head.
A better alternative is to use the defer attribute in the script tag.
For example:
<script type="text/javascript" src="script.js" defer></script>
or
<script type="text/javascript" src="script.js" defer="defer"></script>
The second option is kind of unneccessary though. This attribute is pretty well supported. Internet Explorer has supported it since version 5.5 though apparently it is "buggy" through IE9. It has been fully supported since FireFox 3.5, Chrome 8.0, Safari 5.0. It also works with all current mobile browsers. I guess it is not supported by any Opera browsers though.

jQuery not getting called in all browsers

Disclaimer: I am new to jQuery.
I am trying to implement a fadeOut effect in jQuery for a div block, and then fadeIn effect on two other div blocks.
However, these effects are only working in the Chrome browser (i.e. they won't work in Safari, FireFox, Opera) which is rather perplexing to me. I have tried clearing my cache in case it was storing an old file, but none of that seemed to do anything.
Basic idea (stored in mainsite.js file):
$("#videoThumbnail_XYZ").click(function () {
$("#thumbnailDescription_XYZ").fadeOut(300);
$("#videoPlayer_XYZ").delay(300).fadeIn(100);
$("#videoHiddenOptions_XYZ").delay(300).fadeIn(100);
});
So when a div tag with the id of videoThumbnail_XYZ is clicked, it starts the fadeOut and fadeIn calls on the other div tags.
I am loading my javascript files into the page in this order (so jQuery is loaded first):
<script src="http://code.jquery.com/jquery-1.4.4.js"></script>
<script async="" type="text/javascript" src="javascripts/mainsite.js"></script>
Any guidance you could give is greatly appreciated!
Make sure the DOM is fully loaded before your code runs.
A common way of doing this when using jQuery is to wrap your code like this.
$(function() {
$("#videoThumbnail_XYZ").click(function () {
$("#thumbnailDescription_XYZ").fadeOut(300);
$("#videoPlayer_XYZ").delay(300).fadeIn(100);
$("#videoHiddenOptions_XYZ").delay(300).fadeIn(100);
});
});
This is a shortcut for wrapping your code in a .ready() handler, which ensure that the DOM is loaded before your code runs.
If you don't use some means of ensuring that the DOM is loaded, then the #videoThumbnail_XYZ element may not exist when you try to select it.
Another approach would be to place your javascript code after your content, but inside the closing </body> tag.
<!DOCTYPE html>
<html>
<head><title>your title</title></head>
<body>
<!-- your other content -->
<script src="http://code.jquery.com/jquery-1.4.4.js"></script>
<script async="" type="text/javascript" src="javascripts/mainsite.js"></script>
</body>
</html>
If mainsite.js is being included before your div is rendered, that might be throwing the browsers for a loop. Try wrapping this around your click handler setup:
$(document).ready(function(){
// your function here
});
That'll make sure that isn't run before the DOM is ready.
Also, you might consider putting the fadeIn calls in the callback function of your fadeOut, so if you decide to change the duration later on, you only have to change it in one place.
The way that'd look is like this:
$("#thumbnailDescription_XYZ").fadeOut(300,function(){
$("#videoPlayer_XYZ").fadeIn(100);
$("#videoHiddenOptions_XYZ").fadeIn(100);
});
I see you have a delay set to the same duration your fadeOut is, I would recommend instead of delaying which in essence your waiting for the animation to complete that instead you use the callback function.
$("#videoThumbnail_XYZ").click(function () {
$("#thumbnailDescription_XYZ").fadeOut(300, function() {
$("#videoPlayer_XYZ").fadeIn(100);
$("#videoHiddenOptions_XYZ").fadeIn(100);
});
});
While JavaScript provides the load event for executing code when a page is rendered, this event does not get triggered until all assets such as images have been completely received. In most cases, the script can be run as soon as the DOM hierarchy has been fully constructed. The handler passed to .ready() is guaranteed to be executed after the DOM is ready, so this is usually the best place to attach all other event handlers and run other jQuery code.
$(document).ready(function(){
$("#videoThumbnail_XYZ").click(function () {
$("#thumbnailDescription_XYZ").fadeOut(300);
$("#videoPlayer_XYZ").delay(300).fadeIn(100);
$("#videoHiddenOptions_XYZ").delay(300).fadeIn(100);
});
});
All three of the following syntaxes are equivalent:
* $(document).ready(handler)
* $().ready(handler) (this is not recommended)
* $(handler)

Categories

Resources