How can I ensure consistent loading of dynamic references in my webapp using JQuery?

34 views Asked by At

I'm currently developing the game "Battleships" as a webapp using Spring WebSocket. I'm using a dedicated ScriptLoader-Javascript to load all other javascripts that are required for my main html. The custom javascripts are short and separated to make the whole script more clear. The ScriptLoader looks like this:

loadScript("https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js");
loadScript("https://ajax.googleapis.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js",);
loadScript("https://cdnjs.cloudflare.com/ajax/libs/stomp.js/2.3.3/stomp.min.js");
loadScript("https://cdnjs.cloudflare.com/ajax/libs/sockjs-client/1.5.2/sockjs.min.js");

loadScript("/javascripts/gamescripts/ConstLoader.js");

window.onload = function (){
    loadScript("/javascripts/gamescripts/VarLoader.js");
    loadScript("/javascripts/gamescripts/SupportFunctions.js");
    loadScript("/javascripts/gamescripts/SocketLoader.js"); 
    loadScript("/javascripts/gamescripts/SubscribeFunctions.js"); 
    loadScript("/javascripts/gamescripts/ButtonHandlers.js"); 
    loadScript("/javascripts/gamescripts/FrontendHandlers.js"); 
    loadScript("/javascripts/gamescripts/DnDHandlers.js"); 
    loadScript("/javascripts/gamescripts/AutoPlaceFunctions.js"); 
    loadScript("/javascripts/gamescripts/ResetFunctions.js"); 
    loadScript("/javascripts/gamescripts/RotateFunctions.js"); 
}

function loadScript(pathOrUrl){
    let script = document.createElement("script");
    script.src = pathOrUrl;
    document.head.appendChild(script);
}

The problem im encountering for some time now is, that the "VarLoader.js"-script, that consists of dynamic jquery references, doesn't load some of the dynamic references correctly. This problem manifests itself as soon as any functionality (buttons, drag-and-drop) gets used by the affected instance. This problem only occurs in some instances of my webapp, so i'm kind of confused about why it's occuring. Here's my "VarLoader.js"-script for reference (the references get used by all following scripts):

//defines board element references
var shipList = $(".draggableShip");
var ownDivs = $('.ownDiv');
var enemyDivs = $('.enemyDiv');
var ownBoard = $("#ownBoard");
var enemyBoard = $("#enemyBoard");

//defines button references
var readyButton = $("#readyButton");
var resetButton = $("#resetButton");
var autoPlaceButton = $("#autoPlaceButton");
var surrenderButton = $("#surrenderButton");
var rematchButton = $("#rematchButton");
var backButton = $("#backButton");

//defines dropdown element references
var dropdownButton = $("#dropdownButton");
var shipDropdown = $("#dropdownContent");
var gameRulesButton = $("#gamerulesButton");
var gameRulesDropdown = $("#gamerules");

//defines label parent div references
var winnerDiv = $(".winnerDiv");
var secondPlayerDiv = $("#secPlayerD");

//defines image references
var leftImage = $("#leftImage");
var rightImage = $("#rightImage");

//defines custom attributes
var readyToggle = false; //"active" property of the ready button
var rematchToggle = false; //*active* property of the rematch button
var enemyDivActive = new Array(100).fill(true); //property of the enemyDivs, that determine if they are clickable

I've tried solving the problem by placing the "VarLoader.js"-script outside of my window.onload function, i've tried to defer all following scripts and i've also tried to load all following scripts in a try-catch (despair). The error kept occuring occasionally and i have no idea how to load the dynamic references consistently correct. An example for an error thats occuring looks like this:

"ButtonHandlers.js 23:4" readyButton not defined
1

There are 1 answers

0
Tired8296 On

I found a solution for my problem that delayed all following scripts after the executed "VarLoader.js"-script. To achieve this i am using the jquery-function "$.getScript()". This function has the ".done"-property to execute code after it got loaded. By loading the "VarLoader.js"-script using this function i was able to delay all dependant, following scripts. My current code looks like this:

//loads every external javascript
loadScript("https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"); //imports jquery
loadScript("https://ajax.googleapis.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js"); //imports jquery ui
loadScript("https://cdnjs.cloudflare.com/ajax/libs/stomp.js/2.3.3/stomp.min.js"); //imports stomp.js (websocket library)
loadScript("https://cdnjs.cloudflare.com/ajax/libs/sockjs-client/1.5.2/sockjs.min.js"); //imports sock.js (websocket library)

loadScript("/javascripts/gamescripts/ConstLoader.js"); //loads every static resource

window.onload = function (){ //loads every javascript that requires a fully loaded html and imported libraries

    //ensures that all dynamic resources got loaded before the other scripts start loading
    $.getScript("/javascripts/gamescripts/VarLoader.js").done(function(script, textStatus){ //loads every dynamic resource

        loadScript("/javascripts/gamescripts/SupportFunctions.js"); //loads support functions used by several other scripts
        loadScript("/javascripts/gamescripts/SocketLoader.js"); //loads javascript used for socket communication
        loadScript("/javascripts/gamescripts/SubscribeFunctions.js"); //loads javascript used for dealing with server answers
        loadScript("/javascripts/gamescripts/ButtonHandlers.js"); //initializes the buttons with handlers
        loadScript("/javascripts/gamescripts/FrontendHandlers.js"); //loads javascript used for general frontend
        loadScript("/javascripts/gamescripts/DnDHandlers.js"); //loads the javascript used for enabling correct drag and drop functionality on ships
        loadScript("/javascripts/gamescripts/AutoPlaceFunctions.js"); //loads the function used for automatic placement of all ships
        loadScript("/javascripts/gamescripts/ResetFunctions.js"); //loads the functions used for resetting ships or the whole game
        loadScript("/javascripts/gamescripts/RotateFunctions.js"); //loads the functions used for rotating ships while dragging
    });
}

//loads a javascript dependant on the given path/url
function loadScript(pathOrUrl){
    let script = document.createElement("script");
    script.src = pathOrUrl;
    document.head.appendChild(script);
}