Dynamic Loading of Multiple Scripts on a Webpage with Dependencies in JavaScript

I am currently working on developing a page constructor entirely using JavaScript. The issue arises when I dynamically add two scripts to the page that are dependent on each other. For instance, in this scenario, I am loading jQuery from a CDN, and in the second script, I attempt to call a jQuery function to modify the title text. However, since the first script hasn't loaded yet, I encounter the error ReferenceError: $ is not defined.

What would be the optimal approach in this situation? Should I wait to load the next script until the previous one is fully loaded?

One thing to note is that I prefer not to utilize external libraries like RequireJS, as it would require constant updating whenever the plugin is updated, making it unfeasible in this case.


EXAMPLE

Here are my JS classes:

NS.Script = function(nHasCode, nType, nSrc, nContent){
  this.hasCode = nHasCode;
  this.src = nSrc;
  this.type = nType;
  this.content = nContent;
};

NS.Page = function(){
  this.id;
  this.isIndex;
  this.title;
  this.metas = [];
  this.links = [];
  this.styles = [];
  this.scripts = [];
  this.body;
};

NS.Page.prototype.addScript = function(hasCode, type, src = null, content = null){
  var aux = new NS.Script(hasCode, type, src, content);
  var pageScripts = this.scripts;
  pageScripts.push(aux);
};

NS.Pages = {
  load: function(page){
    document.body.innerHTML = page.body;
    document.title = page.title;
    page.scripts.forEach(function(pageScript) {
      if(pageScript.hasCode){
        document.write("<script type="+pageScript.type+">"+pageScript.content+"<\/script>");
      }else{
        var s = document.createElement( 'script' );
        s.setAttribute( 'type', pageScript.type );
        s.setAttribute( 'src', pageScript.src );
        if (s.readyState){  
          script.onreadystatechange = function(){
            if (s.readyState == "loaded" ||
                    s.readyState == "complete"){
              s.onreadystatechange = null;
              //At this point, I may need to call the script load of each dependency
            }
          };
        } else {  
          s.onload = function(){
            //callback();
            //At this point, I may need to call the script load of each dependency
          };
        }
        document.getElementsByTagName("head")[0].appendChild( s );
      }
    });
  }
};

Lastly, I create a new page and add two scripts:

var page = NS.Pages.new("Test", "Page 1");
page.title = "Page title";
page.isIndex = true;
page.body = "<h1 id='title'>Page title with H1</h1><p>This could be a paragraph</p>";
page.addScript(false, 'text/javascript', 'https://code.jquery.com/jquery-2.2.3.min.js');
page.addScript(true, 'text/javascript', null, "$('#title').text('The new title configured with jQuery');");
NS.Pages.load(page);

Answer №1

<script type="text/javascript">
function loadJSFile(filePath)
{
    var request = new XMLHttpRequest();
    request.open("GET", filePath, false); // 'false': synchronous.
    request.send(null);

    var head = document.getElementsByTagName("head")[0];
    var newScript = document.createElement("script");
    newScript.type = "text/javascript";
    newScript.text = request.responseText;
    head.appendChild(newScript);
}

loadJSFile("script1.js");
loadJSFile("script2.js");
</script>

Original source of the code snippet:

Answer №2

It seems to be a classic case of a chicken and egg dilemma. The issue arises from the fact that dynamically inserted <script> tags come with a default "async" property, leading to execution in an unpredictable order. As mentioned by Mozilla, you have the option to request synchronization:

var s = document.createElement( 'script' );
s.setAttribute( 'type', pageScript.type );
s.setAttribute( 'src', pageScript.src );
s.async = false;

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Invalid component exception: The element type is not valid in React Native

In my React Native App.js file, I have included the following code snippet import { StatusBar } from 'expo-status-bar'; import React, { useRef } from 'react'; import { StyleSheet, Text, View, Canvas } from 'react-native'; impo ...

Encountering an abundance of concurrent requests using NodeJS and request-promise

I am currently working on a NodeJS project that involves a large array of about 9000 elements containing URLs. These URLs need to be requested using the "request-promise" package. However, making 9000 concurrent GET requests to the same website from the sa ...

Performing ad-hoc queries on a Postgresql database using Node.js and Express to manipulate row data

I am faced with a challenge of selecting one entry randomly from a table containing 46 entries, and then passing the data from that particular query to my handlebars files. I am unsure about how to approach the task of randomly querying the database and re ...

Incorporate an external script into your Vue.js application

Seeking to integrate a simple JavaScript script with an external link to the library into my Vue.js application, I have encountered the following: <script type="text/javascript" src="https://my_site/index.js"></script> <link rel="styleshee ...

What methods can I use in Mocha with Sinon for testing multiple callbacks?

My code involves a function with asynchronous operations and multiple callbacks var f = (cb1, cb2) => { return new Promise((resolve, reject) => { /* ... */ }); }; During testing, I wanted to use sinon to create spies var cb1Spy = sinon.spy(); va ...

Arrange a JavaScript map based on its values and ensure that a specific field index remains at the top position

I'm sure this question may seem simple to some, but as a JavaScript novice, I couldn't find the answer myself. Here is the code snippet I'm working with: Let map = new Map<String,String> map.set('0', select) map.set('1&a ...

Publishing a NodeJS + Express + MySQL application on Heroku involves deploying the server side only, excluding the React frontend

I have a React + NodeJS + Express + MySQL project that we're trying to deploy on Heroku. It's set to auto deploy whenever something is pushed to the master branch of GitHub. The problem we're facing is that while the server routes are deplo ...

Calendar complete: ActiveRecord::RecordNotFound (Event with 'id' = update not found)

I'm currently facing an issue with integrating FullCalendar into my rails application. Specifically, I am encountering difficulties with saving after performing drag-and-drop actions. Within my application, I have two models - Event and Workout. The ...

Ensure Angular JS includes a space or special character after applying a currency filter

Is there a way to include a space or special character after the "₹" symbol? Desired output: ₹ 49 Current output: ₹49 HTML - {{cart.getTotalPrice() | currency:"₹"}} ...

Is comparing strings in JavaScript as efficient as comparing numbers?

Considering creating a JavaScript enum library involves deciding how to store the values, I'm at a crossroads. Should I opt for speed in comparison or prioritize readability during debugging by using strings or numbers? While objects are an option too ...

Toggle visibility on the child DOM element of each item in the v-for loop

Here's an example of a template: <template> <table class="table table-hover"> <tbody> <tr> <th style="width:260px">Info</th> <th>Deta ...

Updating the columns in a row by clicking the refresh button with ajax in a JSP file

Hey there! I have a table on my JSP page with refresh buttons at the row level. When I click the refresh button, it should check the database and update those two columns with new values. Below is the code snippet for my JSP page: <script src="js/jque ...

Producing asynchronous JavaScript events using a browser extension (NPAPI)

Currently in the process of developing a web browser plugin using NPAPI. The issue I am facing is that my plugin requires a worker thread to handle certain tasks, and I need to pass events back to JavaScript as the worker progresses. However, due to the N ...

Getting rid of background color in a tooltip using Material UI

I'm currently tackling an issue with Material UI's tooltip. I can't seem to find a way to make the background of the tooltip completely transparent. By default, it displays with a grey background and white text. Changing the background color ...

Is there a method to avoid the default state from loading upon the initialization of my AngularJS application?

Context In order to ensure that the user has an authenticated session, my app must send a request to the server before loading the first state. Depending on the URL, if the user is not authenticated, they should be redirected to the login page. For examp ...

Tips for incorporating local storage into Angular applications

After successfully creating a table using Angular, I decided to incorporate a local storage feature. Despite my efforts, I'm struggling with implementing gsklee/ngStorage and gregory/angular-local-storage libraries into my existing code. Could someon ...

Improving sharing functionality across multiple VuGen scripts executed through Performance Center

I have multiple VuGen scripts that utilize the Web/HTTP protocol with javascript. Currently, I am using VuGen 12.53 (patch 4) and have a common login.js action in all of my scripts. Whenever I need to make changes to the login action, I have to update ever ...

The URL provided by window.location is not accurate

I'm facing an issue with the code window.history.pushState("", "title", myCtxURLVersion); which is supposed to change the current URL of the page. However, when I implement this code, the URL displayed is incorrect. For example, even though the brows ...

Ways to convert a jQuery object into HTML that can be utilized?

When running the code below, an alert message of "object Object" is displayed: var shipImgs = $("#div").children(); alert(shipImgs); The container with id "div" includes a total of 4 children (image tags). <div id="div"> <img src="/imgs/spa ...

Converting Greek text to UTF-8 using Javascript

Currently, I am working on a project with my teacher to digitalize a Greek textbook by transforming it into an online application. This process involves the conversion of a Shapefile, which draws polygons on maps along with polygon descriptions, and mappin ...