Object.onload in Internet Explorer 6, 7 and 8 - javascript

I have an application that must be able to do the following:
var script1 = document.createElement('script');
script1.src = myLocation + 'script1.js';
script1.type = 'text/javascript';
document.body.appendChild(script1);
script1.addEventListener('load', function () {
var script2 = document.createElement('script');
script2.src = myLocation + 'script2.js';
script2.type = 'text/javascript';
document.body.appendChild(script2);
script2.addEventListener('load', function () {
var script3 = document.createElement('script');
script3.src = myLocation + 'script3.js';
script3.type = 'text/javascript';
document.body.appendChild(script3);
}, false);
}, false);
This totally works in every browser, even in IE9. In every other IE, it doesn't. I have tried falling back to Object.attachEvent('onload', function) but I think only window has that event listener.
Can anyone tell me what is the best way for this to work in every browser?
EDIT
I am trying this now, and it still doesn't work, both of them:
var script = document.createElement('script');
script.src = 'http://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js';
script.type = 'text/javascript';
script.onload = function(){alert('jquery loaded');};
//script.attachEvent('load', function(){alert('jquery loaded');});
document.body.appendChild(script);

Internet Explorer, as you may have guessed, does things slightly differently. Instead of onload, an onreadystatechange event will fire. You can then check the readyState property and it can be one of a few different values. You should check for complete or loaded. There's a slight semantic difference between them that I don't remember, but sometimes it will be loaded and sometimes it will be complete.
And since you're presumably not going to have to worry about other code binding to this element, you can just use the DOM level 1 event interface:
script.onreadystatechange = function() {
var r = script.readyState;
if (r === 'loaded' || r === 'complete') {
doThings();
script.onreadystatechange = null;
}
};
(Or you can use a regex above if you're lazy.)

I like how you attach the load event AFTER you add it to the page. Sort of like ringing the doorbell after you open the door.
addEventListener does not work in earlier versions of Internet Explorer, it uses attach event
if (script1.addEventListener){
script1.addEventListener('load', yourFunction);
} else if (script1.attachEvent){
script1.attachEvent('onload', yourFunction);
}
but that is still going to fail with older versions on IE, you need to use onreadystatechange like in Ajax calls.
script1.onreadystatechange= function () {
if (this.readyState == 'complete') yourFunction();
}
So something like this:
function addScript(fileSrc, helperFnc)
var head = document.getElementsByTagName('head')[0];
var script = document.createElement('script');
script.type = 'text/javascript';
script.onreadystatechange = function () {
if (this.readyState == 'complete') helperFnc();
}
script.onload = helperFnc;
script.src = fileSrc;
head.appendChild(script);
}

I have found that readyState is set to 'loaded' for IE8 (IE11 in compatibility mode) so you'll need to cater for both values ('completed'), although I've not seen this other value returned in IE (thanks #chjj).
The following implements a singleton call-back that caters for both 'loaded' events, perhaps it is of use.
function loadScript(url, callback) {
var head = document.head || document.getElementsByTagName("head")[0];
var scriptElement = document.createElement("script");
scriptElement.type = "text/javascript";
scriptElement.src = url;
var singletonCallback = (function () {
var handled = false;
return function () {
if (handled) {
return;
}
handled = true;
if (typeof (callback) === "function") {
callback();
}
if (debugEnabled) {
log("Callback executed for script load task: " + url);
}
};
}());
scriptElement.onreadystatechange = function () {
if (this.readyState === 'complete' || this.readyState === 'loaded') {
singletonCallback();
}
};
scriptElement.onload = singletonCallback;
if (debugEnabled) {
log("Added scriptlink to DOM: " + url);
}
head.appendChild(scriptElement);
}

Related

Cannot call function from dynamically loaded javascript file

I'm loading a javascript external file from another javascript file present in the document and since its loaded, I want to call a function from the loaded js file.
Here is the load function:
function loadScript(url) {
var head = window.top.document.getElementsByTagName('head')[0];
var script = window.top.document.createElement('script');
script.src = url;
script.type= "text/javascript";
head.appendChild(script);
if(script.readyState) { //IE
script.onreadystatechange = function() {
if ( script.readyState === "loaded" || script.readyState === "complete" ) {
script.onreadystatechange = null;
console.log("[BANDEAU] script loaded");
testAlert();
}
};
} else { //Others
script.onload = function() {
console.log("[BANDEAU] script loaded");
testAlert();
};
}
}
So it works nice because the javascript file is succesfuly loaded but I cannot access the testAlert() method from the loaded javascript file, as I try in the code above, right after printing that the script is loaded. When I try to get the type of the function with typeOf on window[testAlert], I get an undefined. But when I try to execute the testAlert() method in the developer console, it works perfectly. Does anyone see what I'm doing wrong ?
Does the position in the DOM between the caller javascript file and the loaded javascript file might be the reason ?
You need to assign the load handlers BEFORE changing the src
function loadScript(url) {
var head = document.getElementsByTagName('head')[0]; // window.top in frames/iFrames
var script = document.createElement('script');
script.type = "text/javascript";
if (script.readyState) { //IE
script.onreadystatechange = function() {
if (script.readyState === "loaded" || script.readyState === "complete") {
script.onreadystatechange = null;
console.log("[BANDEAU] script loaded");
testAlert(); // window.top.testAlert() if needed
}
};
}
else {
script.onload = function() {
console.log("[BANDEAU] script loaded");
testAlert(); // window.top.testAlert() if needed
};
}
script.src = url;
head.appendChild(script);
}
In addition to what mplungjan said, I'm pretty sure you'd have to do an eval() on the loaded script in order to have a legitimate address for the call to testAlert().
Also, check out this link for more info.

Why is this JQuery click function not working? (Recaptcha verify button)

I don't understand why it is not working.
Open link https://www.google.com/recaptcha/api2/demo
Inject jquery in this webpage
Given ReCAPTCHA, select checkbox for “I’m not a robot” and choose photos
Open Chrome console and run code:
$('iframe[src*="frame"]').contents().find('#recaptcha-verify-button').click();
I don't understand why click function (on verify button from js) not working (nothing happens, no error, nothing).
Edit:
Inject jQuery:
if (typeof jQuery == 'undefined') {
loadScript('https://code.jquery.com/jquery-1.11.3.min.js', jQueryReady);
}
function loadScript(url, callback){
var head = document.getElementsByTagName('head')[0];
var script = document.createElement('script');
script.type = 'text/javascript';
script.src = url;
if(!callback) callback = function(){};
if(script.addEventListener) {
script.addEventListener("load", callback, false); // IE9+, Chrome, Firefox
}
else if(script.readyState) {
script.onreadystatechange = callback;
}
head.appendChild(script);
}
Click on “I’m not a robot” working perfect:
$('iframe[src*="anchor"]').contents().find('.recaptcha-checkbox-checkmark').click();
Edit2:
//https://www.google.com/recaptcha/api2/demo
if (typeof jQuery == 'undefined') {
loadScript('https://code.jquery.com/jquery-1.11.3.min.js', jQueryReady);
}
function loadScript(url, callback) {
var head = document.getElementsByTagName('head')[0];
var script = document.createElement('script');
script.type = 'text/javascript';
script.src = url;
if (!callback) callback = function() {};
if (script.addEventListener) {
script.addEventListener("load", callback, false); // IE9+, Chrome, Firefox
} else if (script.readyState) {
script.onreadystatechange = callback;
}
head.appendChild(script);
}
function jQueryReady() {
//working perfect
//$('iframe[src*="anchor"]').contents().find('.recaptcha-checkbox-checkmark').click();
//not working
$('iframe[src*="frame"]').contents().find('#recaptcha-verify-button').click();
}
As Jaromanda X mentions in the comments, it would obviously not work because the jQuery library isn't loaded on that page.
Following your edit, your code throws a security error:
if (typeof jQuery == 'undefined') {
loadScript('https://code.jquery.com/jquery-1.11.3.min.js', jQueryReady);
}
function loadScript(url, callback) {
var head = document.getElementsByTagName('head')[0];
var script = document.createElement('script');
script.type = 'text/javascript';
script.src = url;
if (!callback) callback = function() {};
if (script.addEventListener) {
script.addEventListener("load", callback, false); // IE9+, Chrome, Firefox
} else if (script.readyState) {
script.onreadystatechange = callback;
}
head.appendChild(script);
}
function jQueryReady() {
$('iframe[src*="anchor"]').contents().find('.recaptcha-checkbox-checkmark').click();
}
jquery-1.11.3.min.js:2 Uncaught SecurityError: Failed to read the 'contentDocument' property from 'HTMLIFrameElement': Blocked a frame
with origin "http://www.google.com" from accessing a frame with origin
"https://www.google.com". The frame requesting access has a protocol
of "http", the frame being accessed has a protocol of "https".
Protocols must match.
The iframe is the secure https, whereas the actual demo is on a http location.

Loading a script with Javascript- doesn't work on chrome?

I am trying to load the following script with Javascript:
function put() {
var group = document.getElementById("obj_0123456790");
var children = group.childNodes;
for( var i = 0; i < children.length; i++ ) {
if( (children[i].name == 'movie') || (children[i].name == '') ) {
children[i].src = "http://website.com/song.swf";
}
}
}
if (window.attachEvent) {
window.attachEvent('onload', put);
} else {
if (window.onload) {
var curronload = window.onload;
var newonload = function() {
curronload();
put();
};
window.onload = newonload;
} else {
window.onload = put;
}
}
I load it with the following code:
<script>
var i=document.createElement('script');
i.src="http://website.com/putter.js";
document.head.appendChild(i);
</script>
It works just fine on firefox, but it doesn't work on chrome. How can I make it work on chrome?
1.This function will work cross-browser for loading scripts asynchronously
function loadScript(src, callback)
{
var s,
r,
t;
r = false;
s = document.createElement('script');
s.type = 'text/javascript';
s.src = src;
s.onload = s.onreadystatechange = function() {
//console.log( this.readyState ); //uncomment this line to see which ready states are called.
if ( !r && (!this.readyState || this.readyState == 'complete') )
{
r = true;
callback();
}
};
t = document.getElementsByTagName('script')[0];
t.parent.insertBefore(s, t);
}
2.If you've already got jQuery on the page, just use
$.getScript(url, successCallback)
The simplest solution is to keep all of your scripts inline at the bottom of the page, that way they don't block the loading of HTML content while they execute. It also avoids the issue of having to asynchronously load each required script.
If you have a particularly fancy interaction that isn't always used that requires a larger script of some sort, it could be useful to avoid loading that particular script until it's needed (lazy loading).
3.Example from Google
<script type="text/javascript">
(function() {
var po = document.createElement('script'); po.type = 'text/javascript'; po.async = true;
po.src = 'https://apis.google.com/js/plusone.js?onload=onLoadCallback';
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(po, s);
})();
</script>
4.You might find this wiki article interesting : http://ajaxpatterns.org/On-Demand_Javascript
5.If its any help take a look at Modernizr. Its a small light weight library that you can asynchronously load your javascript with features that allow you to check if the file is loaded and execute the script in the other you specify.
Here is an example of loading jquery:
Modernizr.load([
{
load: '//ajax.googleapis.com/ajax/libs/jquery/1.6.1/jquery.js',
complete: function () {
if ( !window.jQuery ) {
Modernizr.load('js/libs/jquery-1.6.1.min.js');
}
}
},
{
// This will wait for the fallback to load and
// execute if it needs to.
load: 'needs-jQuery.js'
}
]);

Include the jquery file dynamically [duplicate]

This question already has answers here:
Load jQuery with Javascript and use jQuery
(9 answers)
Closed 9 years ago.
I want to include the jquery file dynamically when I need to it.
But there is a problem, the error message that appear $ is not defined
What I done:
// include the file dynamically.
var parent, script;
parent = document.getElementsByTagName('head')[0];
script = document.createElement('script');
script.type = "text/javascript";
script.src = "includes/jquery.js";
parent.appendChild(script);
// The usage
$('#box').remove();
For IE, I think you need to use the onreadystatechange callback. E.g.
script.onload = script.onreadystatechange = function() {
if (!script.readyState || script.readyState == 'loaded' ||
script.readyState == 'complete') {
$('#box').remove();
}
};
Handle onload event to make sure your script is loaded before you use it
script.onload = function () { $('#box').remove() }
parent.appendChild(script);
try this:
(function () {
function loadScript(url, callback) {
var script = document.createElement("script")
script.type = "text/javascript";
if (script.readyState) { //IE
script.onreadystatechange = function () {
if (script.readyState == "loaded" || script.readyState == "complete") {
script.onreadystatechange = null;
callback();
}
};
} else { //Others
script.onload = function () {
callback();
};
}
script.src = url;
document.getElementsByTagName("head")[0].appendChild(script);
}
loadScript("includes/jquery.js", function () {
//jQuery loaded
console.log('jquery loaded');
$('#box').remove();
});
})();

Anonymous functions doesn't work in Internet Explorer

I am using the following code snippet to load a javascript asynchronously, in a non-blocking manner. It works across Chrome, FF but fails to work in Internet Explorer.
I am running IE8 and can't hit the onload function in IE for the below code;
<script type="text/javascript">
(function () {
var s = document.createElement('script');
s.type = 'text/javascript';
s.async = true;
s.src = 'js/load_outer.js';
s.onload = function () {
alert("Loaded");
}
var x = document.getElementsByTagName('script')[0];
x.parentNode.insertBefore(s, x);
})();
</script>
Could anyone please help me identify the mistake?
Thanks
IE (earlier than 9) doesn't support onload event for <script> element, use onreadystatechange instead:
var complete = false;
script.onload = script.onreadystatechange = function() {
if (!complete && (!this.readyState || this.readyState === 'loaded' || this.readyState === 'complete')) {
complete = true;
// your callback code here
}
}

Categories

Resources