11485 sujets

JavaScript, DOM et API Web HTML5

Est-il possible qu'un javascript appelle plusieurs autres javascripts ?
Je veux dire par là : puis-je avoir un appel de la forme :

<html>
...
<script type="text/javascript"
  src="http://monsite/javascriptprincipal.js">
</script>
...
</html>


... et un script javascriptprincipal.js de la forme :
...
if (condition)
  include(javascript1.js);
else 
  include(javascript2.js);
...


en sachant que je met include sans connaître le mot clé et sans savoir si c'est possible. C'est juste ce que je voudrais faire =)

Peut-être peut-on faire ça en AJAX....
Merci !!!
Modifié par yann12100 (05 Dec 2005 - 09:14)
Bonjour,
C'est faisable avecXMLHttpRequest :


function include (url) {
var xhr;
if (window.XMLHttpRequest) xhr = new XMLHttpRequest();
else if (window.ActiveXObject) xhr = new ActiveXObject("Microsoft.XMLHTTP");


if (xhr == null) throw new Error("XMLHttpRequest non supporté");

xhr.open("GET", url, true);
xhr.onreadystatechange = function () {
if (this.readyState == 4 && this.status == 200) {
setTimeout(this.responseText, 0);
}};

xhr.send(null);
}
Euh... Je ne comprend pas ce que XHR viens faire dans cette histoire !?

Tu pourrais préciser un peu ton idée ?
Héhé, c'est assez simple et astucieux, en fait.
Il charge le fichier javascript avec le xhr et se sert du settimeout pour l'interprèter.

Ça fait une fonction include normale, quoi Smiley smile
Lanza a écrit :
Héhé, c'est assez simple et astucieux, en fait.
Il charge le fichier javascript avec le xhr et se sert du settimeout pour l'interprèter.

Ça fait une fonction include normale, quoi Smiley smile


Ne compte pas sur le setimeout pour ce genre de chose. le callback est là pour ça, voir la doc sur XHR.
tahnh a écrit :

Ne compte pas sur le setimeout pour ce genre de chose. le callback est là pour ça, voir la doc sur XHR.

Que veux-tu dire par "callback" ? Je ne comprends pas de quoi tu parles là.

En fait, il faut quand même que j'explique pourquoi j'ai mis setTimeout et pas eval, ça aurait été aussi une solution possible.

Admettons que mon fichier inclus contienne ceci :


var a = 100;
function b (c) { alert(c); }


Eval exécute le code et l'interprète comme étant à la suite du code normal.
SetTimeout, par contre, exécute le code hors de tout contexte.

Donc si on avait pris eval, si on schématise, on aurait eu ceci :


xhr.onreadystatechange = function () {
if (this.readystate == 4 && this.status == 200) {
var a = 100;
function b (c) { alert(c); }
}
}


Le bout de code "schématisé" s'explique de lui-même, je pense que vous avez compris où pourrait être le problème... Si le code du fichier inclus ne contenait que des appels "statiques", aucune définition de fonction, il n'y aurait pas eu de problème.
Vu comment vous vous prenez la tête avec XHR, il est sans doute plus simple de metre en oeuvre la solution que je propose.

XHR est vraiement plus preformant pour le traitement de donnée XML... pour de simple inclusion, c'est un peut une usine a gaz... non ?
Je ne pige pas vraiment pourquoi vous voulez utilisez de l'ajax la dedans ! faut faire gaffe à ne pas l'utiliser de partout.

Perso je me suis fait ce bout de code :


var CSLib = {};

CSLib.jsLoader =
    {
        jsDirectory: 'js/',
        jsFileExtension: 'js?',
        
        load : function(fileName, options)
        {
            if (typeof(fileName) == 'object')
            {
               for (s in fileName)
                    if (typeof(fileName[s]) == 'string')
                        CSLib.jsLoader.load(fileName[s],options);
                return;
            }
            if (this.loaded[fileName] || this.loading[fileName])
                return;
            
            var head = document.getElementsByTagName('head')[0]; 
            
            var script = document.createElement('script'); 
            script.src = this.jsDirectory + fileName + '.' + this.jsFileExtension + '&jsFileName=' + fileName;
            script.type = 'text/javascript';
            
            head.appendChild(script);
            
            with (CSLib.jsLoader)
            {
                options = options || {};
                var emptyFunction = function(){};
                _beginLoading[fileName] = (options.beginLoading || emptyFunction);
                _endLoading[fileName] = (options.endLoading || emptyFunction );
                
                CSLib.jsLoader.beginLoading[fileName] = function(e)
                    {
                        loading[fileName] = true;
                        _beginLoading[fileName](e);
                    };
                CSLib.jsLoader.endLoading[fileName] = function(e)
                    {
                        loading[fileName] = false;
                        loaded[fileName] = true;
                        _endLoading[fileName](e);
                    };
                    
                beginLoading[fileName](fileName);
            }
        },
        loading : {},
        loaded : {}, 
        _beginLoading: function(){},
        _endLoading: function(){},
        beginLoading: function(){},
        endLoading: function(){}
    }

CSLib.jsLoader.load(['prototype','builder','effects','csmarried'], 
{
beginLoading: function(e){alert('fichier ' + e + ' en cours de chargement'},
endLoading: function(e){alert('fichier' + e + 'chargé')}
});



A partir de la je peux faire n'importe ou dans mon code CSLib.jsLoader('file') et ca me fait mon include si necessaire Smiley smile

Autre particularité, et que j'ai géré la fin de chargement des fichiers ... si par exemple vous faites

CSLib.jsLoader.load('GrosNamespace');
GrosNamespace.fonction();

ca risque de vous faire une erreur, car grosNamespace risque de ne pas etre chargé avant l'appel à la fonction GrosNamespace.fonction ....

Je me sert de cette fonction de plus en plus souvent et elle est trés pratique Smiley smile
Ah, pas mal, cette fonction.
Mais il n'y aurait pas une erreur dans ta boucle for s in filename ? tu ne voulais pas plutôt tester filname[s] que s ? parce que s contient le nom de propriété, pas la valeur...
Tu parles bien de ca ?


            if (typeof(fileName) == 'object')
            {
               for (s in fileName)
                    if (typeof(fileName[s]) == 'string')
                        CSLib.jsLoader.load(fileName[s],options);
                return;
            }


Je test bien la valeur : filename[s]
Cela faisait pas mal de temps que je cherchais un code pour inclure du javascript, en m'inspirant du code de CyrilCS et d'Ajax, j'ai créer ce code :
var FileLoader = {};

FileLoader = {
	
	ErrorType : 0,
	Response : '',
	Result : 0,
	
	GetContents : function() {
		
		return((FileLoader.Result > 0 && FileLoader.Response != null) ? FileLoader.Response : '');

	},
	
	ScriptExec : function() {
		
		if(FileLoader.Result > 0 && FileLoader.Response != null) { 
			
			setTimeout(FileLoader.Response, 0); 
			return(true);
			
		} else { return(false); }
		
	},
	
	Load : function (url, callb) {
		
		var xhr;
	
		if(window.XMLHttpRequest) {
			xhr = new XMLHttpRequest();
		} else if (window.ActiveXObject) {
			xhr = new ActiveXObject("Microsoft.XMLHTTP");
		} else {
			throw new Error("XMLHttpRequest non supporté");
		}
	
		if(xhr == null) throw new Error("XMLHttpRequest non supporté");
	
		xhr.open("GET", url, true); 
		
		xhr.onreadystatechange = function () {

			r_status = '';
			r_readyState = '';
			
			try {
				
				r_status = xhr.status;
				r_readyState = xhr.readyState;
				
			} catch(e) {}
			
			if (r_readyState == 4 && r_status == 200) {
		
				FileLoader.ErrorType = 200;
				FileLoader.Response = xhr.responseText;
				FileLoader.Result = 1;
				
				if(callb.Loaded != null) callb.Loaded(url);

				return xhr.responseText;
		
			} else {
				
				if(r_status != null) {

					FileLoader.ErrorType = r_status;
					FileLoader.Response = '';
					FileLoader.Result = -1;
					
					if(callb.OnError != null) callb.OnError(url);
					
				} else {

					FileLoader.ErrorType = 0;
					FileLoader.Response = 0;
					FileLoader.Result = 0;
					
					if(callb.Loading != null) callb.Loading(url);
					
				}
				
			}
			
			
			
		};
		
		xhr.send(null);
		
	},
	
	OnError : function(){},
	OnLoad  : function(){},
	Loaded  : function(){}
	
}


Ce code est different car il permet de charger un fichier peut importe son type, tout en gérant le statut du chargement. Si le code est du Javascript, vous pourrais l'exécuter depuis la fonction ScriptExec().

Exemple :

resultat = FileLoader.Load(
	         'test.js', {
	          OnError: function(e) { alert('Erreur de chargement de '+e+'') },
	          OnLoad:  function(e) { alert('Chargement de '+e+' en cours...') },
	          Loaded:  function(e) { alert('Chargement de '+e+' terminé') }
             }
            ); // Fichier recupéré
            
   FileLoader.ScriptExec(); // On peut l'éxécuter si c'est du Javascript
   alert(FileLoader.GetContents()); // Ou on peut l'utiliser à autre chose...


Personnellement Cyril ton code ne fonctionnais pas chez moi (Firefox et IE). Ce code a été testé sur les dernières versions de Firefox et IE.
Merci a tous pour votre aide Smiley smile