Chargement function dans script src head avec variable

Pour toutes les discussions javascript, jQuery et autres frameworks
Répondre
Jpe54
Messages : 60
Enregistré le : 10 mars 2017, 14:11

Chargement function dans script src head avec variable

Message par Jpe54 » 12 avr. 2020, 15:13

Bonjour,

Soit un fichier My_Liste.js qui sera à charger selon un emplacement variable (par exemple _Xyz). Il contient une function Liste() contenant un tableau à traiter.

Avec un emplacement connu je charge un script src dans le head du code HTML puis le travaille dans le body sans problème.

Du fait de l'inconnu de cet emplacement je charge ce script en utilisant une variable que je transmets en argument lors l'appel du fichier HTML. (Dans le code joint cette variable est "fixée" pour le test.)

Je pense avoir réussi à coder le chargement du script src via le DOM mais cela ne suffit pas à rendre accessible le contenu du fichier js pour trouver la function Liste().

Message en debug : Liste est inaccessible

Je me trouve confronté au mode de chargement, qu'il soit synchrone ou asynchrone ou non, du fichier HTML sans pouvoir le modifier. De fait l'appel de la function Liste() se fait avant le chargement du fichier js.

Comment procéder en javascript pur ? Merci !

Amitiés à tous,

Code du fichier js contenant un tableau :

Code : Tout sélectionner

function Liste() {
// ================================================================================
tabSave[0] = "2003 Epinal/200103010.jpg";
tabSave[1] = "202-10 Epinal/20xxx.txt";
tabSave[2] = "20204-11 Metz/2001zzz.pdf";
// ================================================================================
}
Code du fichier HTML d'appel de ce script :

Code : Tout sélectionner

<!DOCTYPE html>
<html lang="fr">
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    <title>Test 12/04/2020</title>
	<!--
    <script src="Liste.js"></script>
	-->
    <script>
	
	// ************************************************************************************************************
	// ************************************************************************************************************
	
		Source_Variable = "_Xyz";
		
		function loadError(oError) {
			throw new URIError("Le script " + oError.target.src + " n'a pas été chargé correctement.");
		}
		
		function Script_Head(url, onloadFunction) {
			var My_js = document.createElement("script");
			My_js.onerror = loadError;
			if (onloadFunction) { My_js.onload = onloadFunction; }
			document.head.appendChild(My_js);
			My_js.src = url;
			// My_js.async = false; 
			}
		
		My_src = Source_Variable + "/My_Liste.js"
		console.log(My_src);
		
		Script_Head(My_src, function () {
		alert("Le script " + My_src + " est correctement chargé");
		});

	// ************************************************************************************************************
	// ************************************************************************************************************
	
    </script>
</head>
<body>

    <script>
       // Charger Liste
       tabSave = new Array();
       Liste();
	   
		console.log(tabSave[2]);
		
    </script>
</body>
</html>
Fichier TestLoad.zip pour test :
TestLoad.zip
(891 Octets) Téléchargé 295 fois

PS : Ce codage HTML charge corectement le fichier js mais quelle instruction DOM utiliser à la place du fameux document.write(Data_script) ? :

Code : Tout sélectionner

<!DOCTYPE html>
<html lang="fr">
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    <title>Test 12/04/2020</title>

    <script>
	
	// ************************************************************************************************************
	// ************************************************************************************************************
	
		Source_Variable = "_Xyz";
		My_src = Source_Variable + "/My_Liste.js"
		
		var Data_script = '<script src="' + My_src + '"><\/script>';
		
		document.write(Data_script);
		
	// ************************************************************************************************************
	// ************************************************************************************************************
	
    </script>

</head>
<body>

<script>
	
	if(typeof (Liste) !== 'function'){
		alert("function Liste non Chargée.");
		}
	
	if (typeof (Liste) == 'function') {
	   alert("function Liste Chargée.");
       // Charger Liste
       tabSave = new Array();
       Liste();
	   console.log(tabSave[2]);
    }
	   	
    </script>
</body>
</html>
Fichier TestLoad2.zip pour test :
TestLoad2.zip
(748 Octets) Téléchargé 293 fois

Jpe54
Messages : 60
Enregistré le : 10 mars 2017, 14:11

Re: Chargement function dans script src head avec variable

Message par Jpe54 » 13 avr. 2020, 11:03

Autre solution, - compilation du codage de TestLoad2 ci-dessus - , en déterrant mes anciennes (mauvaises) habitudes d'un document.write. Ce codage ne semble pas perturber Edge en mode debug…

Code : Tout sélectionner

        // ========================================================================
        // Charger un script externe source "variable" dans la page HTML
        // ========================================================================

        Source_Variable = "_Xyz";
        document.write('<script src="' + Source_Variable + '/My_Liste.js"></scr' + 'ipt>');
        
        console.log('<script src="' + Source_Variable + '/My_Liste.js"></scr' + 'ipt>');
        
Par contre est-ce une solution pérenne pour l'avenir et je ne vois toujours pas quelle instruction DOM utiliser à la place pour "loader" le contenu du fichier js ... mais en ce domaine je reste un "Bleu".

Réencoder ces différents tableaux dans des fichiers de structure et extension XML, ne permettrait plus un fonctionnement en local...

Code HTML Complet :

Code : Tout sélectionner

<!DOCTYPE html>
<html lang="fr">
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    <title>Test 12/04/2020</title>

    <script>

        // ========================================================================
        // Générer d'un élément DIV id=MyId quelconque dans la page HTML
        // ========================================================================

        function Ajouter_DIV(MyId) {
            var body = document.getElementsByTagName("body")[0];
            e = document.createElement("div");
            e.id = MyId;
            e.innerHTML = ' ';
            body.appendChild(e);
        }

        // ========================================================================
        // Charger un script externe source "variable" dans la page HTML
        // ========================================================================

        Source_Variable = "_Xyz";
        document.write('<script src="' + Source_Variable + '/My_Liste.js"></scr' + 'ipt>');

    </script>

</head>
<body>

    <script>

        if (typeof (Liste) !== 'function') {
            alert("function Liste non Chargée.");
        }

        if (typeof (Liste) == 'function') {
            alert("function Liste Chargée.");
            // Charger Liste
            tabSave = new Array();
            Liste();
            for (var i = 0; i < tabSave.length; i++) {
                Ajouter_DIV("log" + i);
                e.innerHTML = tabSave[i];
            }
        }
        console.log('<script src="' + Source_Variable + '/My_Liste.js"></scr' + 'ipt>');
        console.log(tabSave[2]);


    </script>
</body>
</html>
Fichier TestLoad3 pour test :
TestLoad3.zip
(1.14 Kio) Téléchargé 317 fois

Avatar du membre
webmaster
Administrateur du site
Messages : 563
Enregistré le : 28 févr. 2017, 15:19

Re: Chargement function dans script src head avec variable

Message par webmaster » 13 avr. 2020, 14:00

Bonjour,

Le principe de document.write n'est pas vraiment un probleme. Comme google s'en sert pour afficher ses publicités, cela va durer encore longtemps.

Pour faire du JS plus propre, il serait sans doute utile d'utiliser createElement
https://www.toutjavascript.com/referenc ... lement.php

puis l'ajout dans le DOM avec appendChild
https://www.toutjavascript.com/referenc ... dchild.php

Et ajouter un evenement au script qui détecte la fin du chargement.
C'est nettement plus lourd en code, mais cela a l'avantage d'être asynchrone : le reste de la page n'est pas bloqué.
TJS : 25 ans et mon livre Tout JavaScript chez Dunod
https://www.toutjavascript.com/livre/index.php

Jpe54
Messages : 60
Enregistré le : 10 mars 2017, 14:11

Re: Chargement function dans script src head avec variable

Message par Jpe54 » 13 avr. 2020, 14:31

Bonjour,

Merci pour cette réponse. La méthodologie DOM que vous citez est celle que j'ai mise en œuvre dans le code HTML de départ (TestLoad.zip) et je détecte bien le chargement (correct ou non) du script… mais le contenu n'est pas chargé c'est là mon problème !

Code de test de chargement - sauf erreur - mais l'on reste asynchrone :

Code : Tout sélectionner

Script_Head(My_src, function () {
		alert("Le script " + My_src + " est correctement chargé");
		});
Sinon quel évènement ajouter au script pour détecter une fin de chargement du contenu ? J'ai tenté, sans succès, une boucle de test de la présence de la function Liste() ...

Avatar du membre
webmaster
Administrateur du site
Messages : 563
Enregistré le : 28 févr. 2017, 15:19

Re: Chargement function dans script src head avec variable

Message par webmaster » 13 avr. 2020, 15:26

C'est une bonne question :)

Du coup j'ai rajouté en exemple 2 le chargement d'un .js et la détection de load ou d'error
https://www.toutjavascript.com/referenc ... lement.php
TJS : 25 ans et mon livre Tout JavaScript chez Dunod
https://www.toutjavascript.com/livre/index.php

Jpe54
Messages : 60
Enregistré le : 10 mars 2017, 14:11

Re: Chargement function dans script src head avec variable

Message par Jpe54 » 13 avr. 2020, 17:51

Effectivement la surveillance via l'event onload permet de tester une variable y compris de type tableau… (Var tab = [x,y,z]) qu'elle soit en début ou fin du fichier js.

Mais malgré cela toutes les "function" externalisées dans le script chargé en DOM restent inconnues lors de l'appel dans le fichier HTML…

Exemple avec ce codage :

Code : Tout sélectionner

function ExtraireParam() {
… le code qui va bien ici ...
}
En débug 'ExtraireParam' is not defined

Un test de ce type informe que la fonction est présente mais n'empêche pas l'erreur en debug sauf appel dans la function LoadJS par exemple pour un tableau "à l'ancienne" comme le fichier js Liste() :

Code : Tout sélectionner

js.onload=function() {
 if (typeof (ExtraireParam) == 'function') { console.log("function chargée.");	}
 }

Avatar du membre
webmaster
Administrateur du site
Messages : 563
Enregistré le : 28 févr. 2017, 15:19

Re: Chargement function dans script src head avec variable

Message par webmaster » 13 avr. 2020, 18:27

A mon avis le probleme vient de la fonction elle-meme et pas du chargement différé.

Il faudrait tester la fonction sans la partie chargement externe
TJS : 25 ans et mon livre Tout JavaScript chez Dunod
https://www.toutjavascript.com/livre/index.php

Jpe54
Messages : 60
Enregistré le : 10 mars 2017, 14:11

Re: Chargement function dans script src head avec variable

Message par Jpe54 » 14 avr. 2020, 11:42

Information peut être importante : HTML testé en local

Voici un fichier test zip contenant index_HtmJS.htm / index_HtmJS.htm respectivement sans / avec la partie chargement externe…
HtmJS ou LoadJS.zip
(2.02 Kio) Téléchargé 292 fois
En présence de LoadJS chargé avec l'information "text/javascript" ou non, l'appel de n'importe quelle "function" contenu dans le fichier js pose problème… pourtant un test sur l'event onload renvoie un résultat Ok !

J'avoue être perplexe ! (test sous Windows 10 avec Edge / Firefox / Chrome avec un comportement identique)

NB : Ceci ne devrait plus avoir une grande importance car devenu - sauf erreur - facultatif avec la balise <script>… Mais pour respecter votre code avec ce type d'appel, je me suis permis d'ajouter sur LoadJS :

Code : Tout sélectionner

js.type = "text/javascript";

Avatar du membre
webmaster
Administrateur du site
Messages : 563
Enregistré le : 28 févr. 2017, 15:19

Re: Chargement function dans script src head avec variable

Message par webmaster » 14 avr. 2020, 11:55

Ok, j'ai compris

Dans le fichier index_LoadJS.htm, il faut faire les traitements en mode asynchrone
Et donc mettre tous les traitements directement après console.log(message);
La fonction loadJS() devient :

Code : Tout sélectionner

        function loadJS() {
            var js = document.createElement("script");
            js.type = "text/javascript";
            js.src = "Script_Commun.js";
            js.onerror = function () { console.log("Erreur de chargement du script"); }
            js.onload = function () {
                console.log("source.js chargé correctement. Vous pouvez faire vos traitements ici");
                console.log("Donc la variable message est bien créée et vaut :");
                console.log(message);
				Ajouter_DIV("logTest");
				e.innerHTML = "Pour test Tout_HTML.js externe";
				Ajouter_DIV("log01");
				e.innerHTML = message;
            }

            document.body.appendChild(js);
        }
TJS : 25 ans et mon livre Tout JavaScript chez Dunod
https://www.toutjavascript.com/livre/index.php

Jpe54
Messages : 60
Enregistré le : 10 mars 2017, 14:11

Re: Chargement function dans script src head avec variable

Message par Jpe54 » 14 avr. 2020, 14:06

En attendant votre réponse j'ai fait une recherche sur les instructions async et defer... Visiblement elles restent d'actualité bien que tous les navigateurs actuels soient asynchrone… reste à connaitre l'utilité des valeurs false ou true et sur quelle type de code vu les performances des machines actuelles.

vu ici : https://javascript.info/script-async-defer et https://javascript.info/onload-ondomcontentloaded

Mais effectivement, mettre tous les traitements directement dans LoadJS est une solution…

Finalement grâce à la réécriture DOM - suite à vos explications de départ pour virer les document.write - de l'intégrité de mes pages HTML, hormis le chargement head de fichiers js externe "fixe", cela ne nécessite pas de grosse modification du codage.

Reste que je souhaite continuer d'approfondir ce langage et visiblement le confinement en est le moment idéal !

Merci encore pour le temps que vous m'avez consacré !

Répondre