Michael
Michael

Reputation: 33297

How can I check if a JS file has been included already?

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

Answers (6)

Ivan Chaer
Ivan Chaer

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

user8333817
user8333817

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

cwallenpoole
cwallenpoole

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

Mims H. Wright
Mims H. Wright

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

Geeky Guy
Geeky Guy

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

UweB
UweB

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

Related Questions