Reputation: 33297
I have split my javascript in different files. I want to prevent, that javascript files are loaded twice. How can I do that?
Upvotes: 24
Views: 37817
Reputation: 7100
Sometimes the js file was loaded by other means (via js for example).
That's when window.performance
can come in handy. Instead of checking among the script
tags, as suggested in other answers, we can check among the resources loaded, with:
let resources = performance.getEntries()
.filter(e => e.entryType === 'resource')
.map(e => e.name);
if (resources.indexOf("//domain.com/path/to/script.js") === -1) {
// Script was not yet loaded.
}
The window.performance
browser compatibility is not bad nowadays:
https://caniuse.com/mdn-api_performance_getentries
If we want to check both the script
tags (for all script tags in the DOM up to that point, including URLs of scripts that may not yet have been loaded) and the window.resources
(for all scripts loaded up to that point, including the ones loaded via js), we could put it together in a function:
function is_script_already_included(src){
const found_in_resources = performance.getEntries()
.filter(e => e.entryType === 'resource')
.map(e => e.name)
.indexOf(src) !== -1;
const found_in_script_tags = document.querySelectorAll(`script[src*="${src}"]`).length > 0;
return found_in_resources || found_in_script_tags;
}
Upvotes: 6
Reputation:
I have tackled this using a generic self-invoking function added at the bottom of each dynamically loaded script.
First - by declaring a new empty array in my base file or a script that will always be loaded, ie the main page in my case index.php
var scriptsLoaded = new Array();
Then add a self executing function to the end of the loaded script:
(function () { scriptsLoaded.push( 'this_script_name.js' ) })();
With this approach any filename in the scriptsLoaded array should only refer to scripts that have been fully loaded already. Simply checking this array would indicate whether a script has been loaded which can also be used as a check for whether to execute on-load style functions for whatever the script is needed for
Upvotes: 2
Reputation: 82018
Here's a test to see if a script has been included based on the path to the js file:
function isScriptAlreadyIncluded(src){
var scripts = document.getElementsByTagName("script");
for(var i = 0; i < scripts.length; i++)
if(scripts[i].getAttribute('src') == src) return true;
return false;
}
It will work for all scripts not loaded through AJAX, though you may want to modify it if you have jsonp code running.
Upvotes: 29
Reputation: 3037
You would need to manually track this and make sure. UweB's suggestion would also work.
You could also check out Require.js which could help you to organize your files.
Upvotes: 0
Reputation: 9399
Don't include them twice. It's you who's doing the includes, after all.
If you're doing those inclusions dynamically, though, you may check whether some global function or object has been set by the script. For example, if I have the script below in a file:
Foo = function () {};
And then I include it like this:
<script src="../foo.js"></script>
Before that script tag is parsed by the browser, Foo
is undefined
. After the tag is processed, Foo
is a Function
. You could use some logic based on that to determine whether you should include some file or not.
Upvotes: 3
Reputation: 4110
Not using any framework (that I know of), you can only do so by checking if a certain variable in the global scope has already been declared.
You could declare a variable var include1 = true;
inside include1.js
, and do something like
if (window.include1 !== true) {
// load file dynamically
}
Upvotes: 1