Cannot include a javascript file from an external javascript file in IE6 - javascript

My problem is that I need to dynamically include a javascript file from another external javascript file. I'm trying to do it by using this function:
function addCustomScriptTag(url) {
var scriptTag=document.createElement('script');
scriptTag.type = 'text/javascript';
scriptTag.src=url;
var myElement = document.getElementsByTagName("head")[0];
myElement.appendChild(scriptTag);
}
The problem happens only in IE6 where trying to append to the head element causes an 'operation aborted' error.
Any help would be appreciated

It depends when you add it to the head DOM element. Operation aborted occurs in all versions of IE because you're trying to modify a DOM element via JavaScript before that DOM element has finished loading, http://support.microsoft.com/default.aspx/kb/927917.
If you need this script loaded right away, you could do an old school document.write to add the script tag, e.g.
<head>
<script>document.write('<script src='yourUrl.js'><\/scr'+'ipt>');</script>
</head>
Otherwise call your function in the body onload via plain old JavaScript or via a framework like jQuery a la document.ready.

Consider using a library like jQuery and then just use the equivalent (if not using jQuery) of getScript. This will handle cross-browser quirks and inconsistencies for the most part.

Append it to the body then. Javascript doesn't have to go exclusively in the <head> of your document.

I steal from the jQuery source:
var head = document.getElementsByTagName("head")[0];
var script = document.createElement("script");
script.src = s.url;
// Attach handlers for all browsers
script.onload = script.onreadystatechange = function(){
if ( !done && (!this.readyState ||
this.readyState == "loaded" || this.readyState == "complete") ) {
done = true;
success();
complete();
// Handle memory leak in IE
script.onload = script.onreadystatechange = null;
head.removeChild( script );
}
};
head.appendChild(script);

I think it's because IE6 doesn't support getElementsByTagName(), try replacing it with document.body.

Related

In an JavaScript If/else statement, how can I render a script tag based on the condition?

Let’s say based on a condition I want a certain JavaScript tag to be added to the HTML.
script1 = '<div id="render_div"></div><script src="script1"></script>';
script2 = '<div id="render_div"></div><script src="script1"></script>';
var someCondition = 0;
if (someCondition == 0) {
//only render script1;
} else {
//only render script2
}
I am thinking of using document.write(script1); but don't think that's the best way.
Below is the condition:
Using an API I am grabbing how many images a user folder has. So if the count is 0 then I want to render script 2. If the count is more than 1 then I want to render script 1.
If you want to avoid using document.write or can't because it is asynchronous, you could dynamically create a script tag and add it to the DOM.
var head = document.getElementsByTagName('head')[0];
var script = document.createElement('script');
script.type = 'text/javascript';
if (someCondition == 0) {
script.src = 'script1';
} else {
script.src = 'script2';
}
head.appendChild(script);
Update for updated requirements:
If the variables need to be HTML, you could use jQuery to append them to the DOM. jQuery will parse the HTML and load the scripts automatically.
if (someCondition == 0) {
$("SOME_SELECTOR").append(script1);
} else {
$("SOME_SELECTOR").append(script1);
}
Answer to Question Asked
This is a nice way to do it (taken from HTML5 boilerplate)
<script>window.jQuery || document.write('<script src="js/vendor/jquery-{{JQUERY_VERSION}}.min.js"><\/script>')</script>
Alternative
YepNope (http://yepnopejs.com/) offers a nice syntax for conditional loading. Usually used in combination with Modernizr (http://modernizr.com/) for conditional polyfills.
If Jquery is being used, I suggest using $.getScript (as suggested by this post here). Otherwise Alexander O'Mara's suggestion seems reasonable.

JavaScript debugging in Internet Explorer (all scripts on page)

I am new to a project in mature stage. There are many JS scripts and libraries on one of the pages, jQuery is used intensively. There is a weird error in IE7/8 only: somewhere in the middle of the page scripts execution jQuery object becomes undefined, so everything else stops working.
There are two scripts specified in the middle of HTML, say, like this:
<script src="script1.js"></script>
<script src="script2.js"></script>
In the end of the script1 a variable called jQuery contains an object as expected, but in the beginning of the script2 variable jQuery is already undefined. What happens in between?
Please, any ideas where to look and how to debug!
Is there a way to control the consequency of script execusion and debug the WHOLE consequent js (including all js includes) on one page?
Thank you! :)
UPDATE. I made a patch: in the end of the script1 I backup the variable:
var jQueryBackup = jQuery;
In the beginning of the script2 I restore it:
if (!jQuery && jQueryBackup) jQuery = jQueryBackup;
It made the script work, but does not explain how could a variable become undefined in between two scripts (I see it as literally between two lines of code).
Your <script> in the middle of the HTML ? Try to put them into the <head>
<head>
<script src="script1.js"></script>
<script src="script2.js"></script>
</head>
if you want to debug , this what i would do :
$.getScript("script1.js").done(function(script, textStatus) {
console.log('script1 is loaded');
$.getScript("script2.js").done(function(s,t){
console.log('script1.js is loaded');
});
})
.fail(function(jqxhr, settings, exception) {
console.log( "Triggered ajaxError handler." );
});
now you can debug it , you can also use native javascript and use onload.
if you need example , let me know.
example : ( this solution will work for IE8+, firefox, chrome )
function handleOnLoad() {
// do the same here for the script.2 file
}
function IEhandleOnLoad() {
if (this.readyState === 'complete' || this.readyState === 'loaded') {
handleOnLoad();
}
}
var s = document.createElement('script');
s.type = 'text/javascript';
s.async = true;
s.onreadystatechange = IEhandleOnLoad;
s.onload = handleOnLoad;
s.src = 'script1.js';

Check if javascript is already attached to a page?

Is there any way to check if javascript file is already attached to the page by its file name.
For eg :
if ("path-to-script/scriptname.js") already embeded
{
call related function
}
else
{
Append '<script src="path-to-script/scriptname.js" type="text/javascript"> </script> '
call related function
}
Basically I dont want 1 script to be attached twice on the same page.
You might not always know what objects or functions a script contains in advance, in such cases you can search for script tags containing the desired src.
With jquery:
$("script[src*='"+scriptName+"']");
Without jquery:
document.querySelector("script[src*='"+scriptName+"']");
You'd need to test whether the actual function from the script file exists, like this:
if (window.function_name) {
// script loaded
} else {
// script not loaded
}
I agree with #zathrus though I think you should be using requirejs for things like this. The idea is that dependencies must be fetched before executing the code. The above method you are using may work but you can not guarantee anything.
RequireJS will beautifully maintain all the dependency loading. It is very easy to learn as well.
Simply check if the library is defined, otherwise import it:
if ( !jQuery ) {
var s = document.createElement('script');
s.type = 'text/javascript';
document.body.appendChild(s);
s.src = "path-to-script/scriptname.js";
void(0);
}
// call function
you really need a script loader.. because as you said you want it specific with the javascript resource filename and this is sort of your javascript files are depending to each other
www.headjs.com
www.modernizr.com
www.yepnopejs.com
I thought this will help you.
if (typeof scriptname== "undefined") {
var e = document.createElement("script");
e.src = "scriptname.js";
e.type = "text/javascript";
document.getElementsByTagName("head")[0].appendChild(e);
}

Is it possible to execute Javascript code that was retrieved using pjax?

Let's say I have some simple Javascript like:
<script>
var hello = function(){
alert("Hello World!");
}
</script>
.. on a page helloworld.html. If I loaded this script block into another page using Pjax. How do I execute the function hello()?
For security reasons, many browsers will not run Javascript injected by innerHTML, which I'm thinking Pjax likely uses. (Here's a minimal example.)
Maybe the solution proposed in Pjax's issue #48 will help
What worked for me was to place my jQuery code in a function, call it
normally on document.ready (for non-pushState browsers), and then bind
the function to pjax:end, i.e.:
$('body').bind 'pjax:end', mainFunction
This is possible with PJAX. You just need to have the script tag with type text/javascript.
Code from PJAX library:
function executeScriptTags(scripts) {
if (!scripts) return
var existingScripts = $('script[src]')
scripts.each(function() {
var src = this.src
var matchedScripts = existingScripts.filter(function() {
return this.src === src
})
if (matchedScripts.length) {
matchedScripts.remove();
}
console.error("FOUND SCRIPTS", scripts, matchedScripts.length);
var script = document.createElement('script')
script.type = $(this).attr('type')
script.src = $(this).attr('src')
document.head.appendChild(script)
})
}

Why doesn't jQuery UI see jQuery?

I've built a JavaScript widget that must be embeddable on any third-party site, in any environment. The widget relies on jQuery and jQuery UI. I followed the steps in How to embed Javascript widget that depends on jQuery into an unknown environment to add jQuery in a responsible manner -- works great for embedding jQuery. But when I try to add jQuery UI, it fails. Here's the code:
(function(window, document, version, callback) {
var j, d;
var loaded = false;
if (!(j = window.jQuery) || version > j.fn.jquery || callback(j, loaded)) {
var script = document.createElement("script");
script.type = "text/javascript";
script.src = "https://ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.min.js";
script.onload = script.onreadystatechange = function() {
if (!loaded && (!(d = this.readyState) || d == "loaded" || d == "complete")) {
callback((j = window.jQuery).noConflict(1), loaded = true);
j(script).remove();
}
};
document.documentElement.childNodes[0].appendChild(script)
}
})(window, document, "1.3.2", function($, jquery_loaded) {
$.getScript('http://ajax.googleapis.com/ajax/libs/jqueryui/1.8/jquery-ui.js', function(){
console.log('loaded');
});
});
When I run this, I get the 'loaded' mesage, followed by an error saying that "$ is undefined" on line 15 of jquery-ui.js. But how can $ be undefined when I'm using $.getScript() to load jQuery UI? And why do I see the message 'loaded' before I get the error? According to the jQuery documentation, getScript shouldn't execute the callback until the script has been loaded and executed.
Is there any way I can use this framework to include jQuery UI, or do I need to use a script loader like RequireJS in order to load everything, enforce dependencies, etc.?
By calling .noConflict(1), the same as .noConflict(true), you're deleting jQuery, just remove the 1. The true argument to .noConflict() tells jQuery to remove not only $, but window.jQuery, which jQuery UI is trying to use afterwards, when it loads.
You can test it here, see there are no errors in the console.

Categories