How to load JS scripts that will add only one additional script - javascript

I have 2 script files that you put in the <head>
However, they share the same Util script file.
I want that in case they are both loaded on the same page, the util file will load only once.
If only one of them is loaded, the util will still be loaded once...
I cant use <script src=...utils.js>... only the 2 scripts
I am using
var s = document.createElement("script");
s.src = s3 + "/js_enc/utils.js";
s.type = "text/javascript";
document.getElementsByTagName("head")[0].appendChild(s);
What is the best way to achieve this?
thanks

This doesn't seem like a problem, since the Util script will only be loaded when it is declared:
<script type='text/javascript' src='util.js'></script>
<script type='text/javascript' src='script1.js'></script>
<script type='text/javascript' src='script2.js'></script>
But if you want to check that the script has been loaded, you could set a global variable in the Util script, something like
var utilFound = true;
Then check in each script to see if it is set or not.
if(!utilFound) { alert("Util not loaded!"); }
You could also toggle the variable depending on some condition, for example:
if(utilFound) {
alert("Util hasn't been accessed yet.");
utilFound = false;
}
else {
alert("Util has already been accessed.");
}
UPDATE
As per your edit, the "check if set and toggle" solution would work fine. If the variable has been set, don't run your document.createElement code.
In your util.js file, add
var utilLoaded = false;
Then in each script, add your snippet, plus a utilLoaded check/toggle:
if(!utilLoaded) {
var s = document.createElement("script");
....
utilLoaded = true;
}

Related

Conditionally load JavaScript file

I need a JS statement that determine which JavaScript file to use.
I have one file:
<script type="text/javascript" src="js/jquery_computer.js"></script>
But when the screen width is less than 500px, I want load another file instead:
<script type="text/javascript" src="js/mobile_version.js"></script>
I have tried everything and it is not working.
You'd have to create that markup yourself in JS. Something like this:
var head = document.getElementsByTagName('head')[0];
var js = document.createElement("script");
js.type = "text/javascript";
if (screen.width > 500)
{
js.src = "js/jquery_computer.js";
}
else
{
js.src = "js/mobile_version.js";
}
head.appendChild(js);
If you want the script loaded asynchronously, the other answers here do that.
If you want it loaded synchronously with page load, this is one of the very, very few remaining valid uses cases for document.write:
<script>
(function() { // Scoping function to avoid globals
var src = /*you want the main version*/ ? "jquery_computer.js" : "mobile_version.js";
document.write('<script src="js/' + src + '"><\/script>');
})();
</script>
(I've removed type because JavaScript is the default, specifying it isn't useful.)
Maybe you can use matchMedia.js and can load a script using jQuery.getScript
$(function(){
if (matchMedia('only screen and (max-width: 500px)').matches) {
$.getScript(...);
}
});
Best would be to use built-in matchMedia API.
var script = document.createElement('script');
script.type='text/javascript';
if(window.matchMedia("(min-width:500px)").matches) {
script.src = 'js/jquery.slitslider.js';
}else{
script.src = 'js/mobile_version.js';
}
document.getElementsByTagName('head')[0].appendChild(script);
Drawback is that it is not supported in IE < 10
You don't need jQuery for this, it suffices to create the <script> tag in the DOM dynamically:
var head = document.getElementsByTagName('head')[0];
var script = document.createElement('script');
script.type = 'text/javascript';
if (<screen-width less than 500>)
script.src = "js/mobile_version.js";
else
script.src = "js/jquery_computer.js";
head.appendChild(script);
$(function(){
var width = $(document).width(),
mobile = 500;
if (width > mobile) {
$('head').append('<script class="desktop" type="text/javascript" src="js/jquery_computer.js"></script>');
$('head').find('.mobile').remove();
}
else
{
$('head').append('<script class="mobile" type="text/javascript" src="js/mobile_version.js"></script>');
$('head').find('.desktop').remove();
}
});
just use if else to detect condition and use class on script element
may be it help
You could use the async import() if you like.
import(condition ? 'js/desktop_version.js' : 'js/mobile_version.js')
In a script tag with <script type="module"> or inside a module loaded with import() from a regular <script> you can also use top-level await in the newest (experimental) browsers
<script type="module">
await import(condition ? 'js/desktop_version.js' : 'js/mobile_version.js')
</script>
But it won't work for every script.
A common reason why is those UMD module bundler that adds a closure (function(global){...}(this)) since this is undefined in modules.
Third party scripts needs to have CORS enable to load
Won't work in IE, but it's dead anyway
See other known differences
you can use $.getScript in jQuery
see here for details

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

Reference External JavaScript File in Function

Is it possible to reference a JavaScript file inside of a JavaScript function?
Therefore i am wanting to convert this:
<script type="text/javascript" src="http://crypto-js.googlecode.com/files/2.5.3-crypto-sha1-hmac.js"></script>
<script type="text/javascript">
var hmacString = Crypto.HMAC(Crypto.SHA1, "Message", "Secret Passphrase", { asString: true });
</script>
In to:
function hmac (input){
var hmacString = Crypto.HMAC(Crypto.SHA1, "Message", "KEY", { asString: true });
return hmacString;
}
I am using a tool called Cast Iron, which therefore restricts JavaScript down to only a function, but i need to call an external file, to load the needed functionality.
Is this even possible?
If I understand correctly, yes you can access functions and classes from one JS file as long as the other class was loaded before you attempt to access it.
So, if some-javascript-file.js has a function named getThings(), then you can do this:
<script type="text/javascript" src="http://cdn.example.com/js/some-javascript-file.js"></script>
<script type="text/javascript">
var things = getThings(); // getThings is a publicly accessible function in an external class.
</script>
Yes, you can load other js files with javascript. Depending on the load state where your function is executed, you may either use
document.write('<script type="text/javascript" src="http://crypto-js.googlecode.com/files/2.5.3-crypto-sha1-hmac.js"'+'><'+'/script>"');
// loads synchronouly and executes
Crypto.HMAC(...); // is available here
Watch out that document.write breaks the whole page once your DOM is loaded. You can also use:
var s = document.createElement("script");
s.type = "text/javascript";
s.src = "http://crypto-js.googlecode.com/files/2.5.3-crypto-sha1-hmac.js";
s.onload = function() {
// the file should be executed now so
Crypto.HMAC(...); // is available here
};
document.head.appendChild(s); // load asychronously
See also Load js from external site on fly
OK the screenshot kind of helps. It seems you want something from an external JS file, and to manipulate it inside this function.
So you could have one javascript file with:
var foo = 'foo'; //this is in the global scope
and then your other file has:
function hmac(key){
alert(document.foo);
}
should access what you want

Categories