Conditionally load JavaScript file - javascript

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

Related

How to run functions from a dynamically loaded script

I am trying to load a js script dynamically in index.html file using appendChild DOM method. And I am trying to use some functions from that dynamically loaded js in next line itself but I am getting error that the specified function is undefined. I understand that this error is because of async behavior of loading scripts in browser. I also used async flag as false but no use. Below are sample code.
<script>
var head = document.getElementsByTagName('head')[0];
var js = document.createElement("script");
js.type = "text/javascript";
js.async = false;
js.src = "https://example.com/test.js"; // There are two variants of test.js is there. Will be changing it dynamically based on conditional check.
head.appendChild(js);
</script>
<script>
test(); // Method inside test.js
</script>
I want test.js to be loaded immediately after executing appendChild code part. Please help me on this. Please suggest if there is any other way for my purpose.
Synchronized XHRs are deprecated. You need to add an event listener so you can call your code as soon as the script is loaded. Example below:
var head = document.getElementsByTagName('head')[0];
var js = document.createElement("script");
head.appendChild(js);
js.onload = function() {
console.log("yes", window.$)
};
js.src = "//code.jquery.com/jquery-3.3.1.min.js";
console.log("nope", window.$)

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';

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

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

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

Categories