Dynamically adding JavaScript files to DOM without duplicates

I’m trying to add content to a <div> using AJAX. I also need to load a JavaScript file in the footer after the AJAX call. My menu uses URL hashes to load content without refreshing the page.

The problem is that when I click the same link multiple times, the JS file gets loaded repeatedly. This causes events to fire multiple times. I want to check if the file is already in the DOM before loading it.

Here’s the code I’m using now:

const ScriptLoader = {
  addScript: function(scriptUrl) {
    const bodyElement = document.querySelector('body');
    const scriptTag = document.createElement('script');
    scriptTag.type = 'text/javascript';
    scriptTag.src = scriptUrl;
    bodyElement.appendChild(scriptTag);
  }
};

ScriptLoader.addScript(scriptUrl);

How can I modify this to prevent duplicate loading? Any tips would be great!

I’ve dealt with this exact issue in a couple of projects. One approach that worked well for me was using a data attribute to mark loaded scripts. Here’s how you could modify your ScriptLoader:

const ScriptLoader = {
  addScript: function(scriptUrl) {
    if (document.querySelector(`script[data-src=\"${scriptUrl}\"]`)) {
      return; // Script already loaded
    }
    
    const bodyElement = document.querySelector('body');
    const scriptTag = document.createElement('script');
    scriptTag.type = 'text/javascript';
    scriptTag.src = scriptUrl;
    scriptTag.setAttribute('data-src', scriptUrl);
    bodyElement.appendChild(scriptTag);
  }
};

This method adds a data-src attribute to each loaded script, which you can then check before loading. It’s straightforward and doesn’t require maintaining a separate list of loaded scripts. Plus, it’s resilient to page refreshes since it checks the actual DOM.

I encountered a similar challenge in a project recently. One effective approach is to maintain a Set of loaded script URLs. Before adding a new script, check if it’s already in the Set. If not, add it to both the DOM and the Set. Here’s a modified version of your ScriptLoader:

const ScriptLoader = {
  loadedScripts: new Set(),
  addScript: function(scriptUrl) {
    if (this.loadedScripts.has(scriptUrl)) return;
    
    const bodyElement = document.querySelector('body');
    const scriptTag = document.createElement('script');
    scriptTag.type = 'text/javascript';
    scriptTag.src = scriptUrl;
    bodyElement.appendChild(scriptTag);
    
    this.loadedScripts.add(scriptUrl);
  }
};

This method ensures each script is loaded only once, regardless of how many times it’s requested. It’s efficient and doesn’t require querying the DOM each time.

hey mike71, i’ve run into that issue b4. try checking if a script’s already there before adding it.

if (!document.querySelector(`script[src=\"${scriptUrl}\"]`)) {
  // add your script
}

that should stop the dupe loading. hope it helps!