Pagina 1 di 2 1 2 ultimoultimo
Visualizzazione dei risultati da 1 a 10 su 15
  1. #1

    [jQuery] caricare un file JS se non già caricato

    Ciao!

    La seguente soluzione funziona SOLO per gli script JS che contengono almeno una funzione.

    codice:
    if(typeof window.FUNCTION_NAME != "function") { 
          $.getScript("FILE_NAME", function(data, textStatus) { 
                alert("lo script è stato caricato!");
          });
    } else {
          alert("NON carico lo script perchè già caricato");
    }
    Come posso invece scrivere una funzione più dinamica/generica che carica un QUALSIASI script JS solo se non già caricato?

  2. #2
    cosa ne pensate della seguente soluzione?

    1) creo un array globale (inizializzato con tutti gli script presenti nell'HEAD)
    2) ogni volta che importo uno script incremento l'array globale con il nome dello script importato
    3) l'array non avrà mai bisogno di essere decrementato perchè gli script durano tutta la durata della pagina (fino a quando non si chiude la pagina o si aggiorna la pagina)
    4) prima di importare uno script, controllo se non è già presente nell'array globale

  3. #3
    Utente di HTML.it
    Registrato dal
    Dec 2010
    Messaggi
    3,660
    puo essere una soluzione, però non hai bisogno di impostare un array globale con gli script presenti, puoi recuperarlo utilizzando la funzione getElementsByTagName("script")

  4. #4
    Senza usare un array globale non riesco.
    Il seguente script è corretto, funziona bene, ma utilizza l'array globale "scripts".
    Se mi sai dire come andrebbe scritta la funzione "findScript" senza l'uso di un array globale allora elimino "scripts".

    codice:
    /**
     * 
     * DESCRIPTION
     * 
     * This script allows you to load the JavaScript scripts, 
     * after checking that they are not already loaded.
     * 
     * ****************************************************************
     * 
     * EXAMPLE
     * 
     * loadScript('./script_1.js');
     * loadScript('./script_2.js','f2');
     * loadScripts(new Array('./script_3.js','./script_4.js'));
     * loadScripts(new Array('./script_5.js','./script_6.js'), 'f6');
     */
    
    var scripts = new Array(); // array (list of script name)
    
    /**
     * Initialize "scripts" array.
     */
    $(document).ready(function() {
    	$('head > script').each(function(index, elt) {
    		scripts.push($(elt).attr("src"));
    	});
    });
    
    /**
     * If it is not already loaded, load a javascript script.
     * If the "callback" parameter is defined, executes "callback" after the script is loaded.
     * 
     * @access	: public
     * @param	: [src] string (script name)
     * @param	: [callback] string (optional: function string)
     */
    function loadScript(src, callback) {
    	if(findScript(src)) {
    		if(callback != undefined)
    			eval(callback+'();');
    	} else {
    		scripts.push(src);
    		$.getScript(src, function(data, textStatus) {		
    			if(callback != undefined)
    				eval(callback+'();');
    		});
    	}
    }
    
    /**
     * If it are not already loaded, load a list of javascript scripts.
     * If the parameter "callback" is defined, after all scripts have been loaded execute "callback".
     * 
     * @access	: public
     * @param	: [srcList] array (list of script name)
     * @param	: [callback] string (optional: function name)
     */
    function loadScripts(srcList, callback) {
    	loadRecursive(srcList, callback, 0);
    }
    
    /**
     * If it are not already loaded, load a list of javascript scripts.
     * If the parameter "callback" is defined, after all scripts have been loaded execute "callback".
     * 
     * @access	: private
     * @param	: [srcList] array (list of script name)
     * @param	: [callback] string (optional: function name)
     * @param	: [i] int (index of srcList)
     */
    function loadRecursive(srcList, callback, i) {
    	if(i == srcList.length) {
    		if(callback != undefined)
    			eval(callback+'();');
    	} else {
    		if(findScript(srcList[i])) {
    			loadRecursive(srcList,callback, i+1);
    		} else {
    			scripts.push(srcList[i]);
    			$.getScript(srcList[i], function(data, textStatus) {
    				loadRecursive(srcList,callback, i+1);
    			});
    		}
    	}
    }
    
    /**
     * Find a script in "scripts" global array.
     * 
     * @access	: private
     * @return	: bool
     * @param	: [src] string (script name)
     */
    function findScript(src) {
    	for(var i = 0; i < scripts.length; i++)
    		if(scripts[i] == src)
    			return true;
    	return false;
    }
    html di test:
    codice:
    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
    <html>
    <head>
    
    	<title>test</title>
    	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
    	
    	<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
    	<script type="text/javascript" src="lazy_loader.js"></script>
    	
    </head>
    <body>
    	
    	<script type="text/javascript">
    		
    		$(document).ready(function() {
    			loadScript('./script_1.js');
    			loadScript('./script_2.js','f2');
    			loadScripts(new Array('./script_3.js','./script_4.js'));
    			loadScripts(new Array('./script_5.js','./script_6.js'), 'f6');	
    		});
    		
    	</script>
    	
    </body>
    </html>
    Tutti i file di test "script_N.js" contengono semplicemente:
    codice:
    alert("caricato");
    function fN() { alert("fN"); }

  5. #5
    Se usi jQuery comunque tanto vale sfruttarlo.
    Potresti fare una cosa elegante tipo:

    codice:
    function loadScript(url, callback){
    if ($('script').filter(function(){$(this).attr('src') === url}).length > 0){
      callback();
    }
    else {
      $.getScript(url, callback);
    }
    }
    Ma non ho presente di preciso come il getScript faccia l'injection dello script nella pagina e sono troppo pigro per guardarci adesso, quindi potrebbe fallire.

    Oppure vai sul sicuro con qualcosa tipo:
    codice:
    function loadScript(url, callback){
      if(!$(document).data(url)){
        $.getScript(url, function(){
          $(document).data(url, true);
          $.isFunction(callback) && callback();
        });
      }
      else { $.isFunction(callback) && callback(); }
    }
    Edit: ti ho aggiunto le callback.
    max

    Silence is better than bullshit.
    @mmarcon
    jHERE, Maps made easy

  6. #6
    Li ho provati, non funzionano!

    Bisogna tener presente anche del caso:
    loadScript('./script_1.js');
    loadScript('./script_1.js');
    loadScript('./script_1.js');
    Lo script deve essere caricato una sola volta (e non tre)! E senza un array globale direi che è impossibile, dato che l'istruzione $.getScript (e .each) vengono eseguite con Ajax e/o in parallelo...?

    Questa istruzione credo sia errata:
    function loadScript(url, callback){
    if(!$(document).data(url)){
    Dato che .data() come primo parametro vuole un elemento DOM e non una stringa.

  7. #7
    Utente di HTML.it
    Registrato dal
    Dec 2010
    Messaggi
    3,660
    codice:
    Dato che .data() come primo parametro vuole un elemento DOM e non una stringa.
    non è cosi, tu fai riferimento a jQuery.data mentre max sta utilizzando .data che accetta come parametro di input una stringa(key). Quindi l'istruzione è corretta, e serve per verificare che lo script non sia già stato caricato precedentemente. il problema potrebbe esserenelle chiamate ajax che credo necessitano di essere sincrone. Se il problema è questo si risolve facilmente utilizzando la funzione $.ajax al posto di $.script. L'array globale non dovrebbe essere cmq necessario.

  8. #8
    Ho riscritto lo script seguendo i tuoi consigli.

    L'istruzione
    if(!$(document).data(urlList[i])){
    viene SEMPRE verificata (non funziona), perchè?

    codice:
    function loadScripts(urlList, callback) {
    	loadRecursive(urlList, callback, 0);
    }
    
    function loadRecursive(urlList, callback, i) {
    	if(!$(document).data(urlList[i])){
    		$.ajax({
    			url: urlList[i]
    		}).done(function(msg) {
    			checkIndex(urlList, callback, i);
    		});
    	}
    	else { checkIndex(urlList, callback, i); }
    }
    
    function checkIndex(urlList, callback, i) {
    	if(i+1 == urlList.length) {
    		//$.isFunction(callback) && callback();
    		if(callback != undefined) eval(callback+'();');
    	} else {
    		loadRecursive(urlList, callback, i+1);
    	}
    }

  9. #9
    Utente di HTML.it
    Registrato dal
    Dec 2010
    Messaggi
    3,660
    codice:
    if(!$(document).data(urlList[i])){
    		$.ajax({
    			url: urlList[i],
                            async: false
    		}).done(function(msg) {
                            $(document).data(urlList[i],true); 
    			checkIndex(urlList, callback, i);
    		});
    	}
    	else { checkIndex(urlList, callback, i); }
    è necessario impostare la chiave a true per fare in modo che nelle sucessive chiamate con chiave uguale non entri nell'if. Inoltre imposta le chiamate come sincrone. Ho fatto un paio di test veloci e sembra sia propio questo il problema

  10. #10
    Grandissimo!
    Vi posto il nuovo script, se non fosse per il fatto che ho usato
    if(callback != undefined) eval(callback+'();');
    al posto di
    $.isFunction(callback) && callback(); // non capisco come andrebbe passata la callback
    sarebbe perfetto:

    codice:
    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
    <html>
    <head>
    	<title>test</title>
    	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
    	<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
    </head>
    <body>
    	
    	<script type="text/javascript">
    		
    		function loadScripts(urlList, callback) {
    			loadRecursive(urlList, callback, 0);
    		}
    	
    		function loadRecursive(urlList, callback, i) {
    			(!$(document).data(urlList[i]))
    			? loadScript(urlList, callback, i)
    			: checkIndex(urlList, callback, i);
    		}
    
    		function loadScript(urlList, callback, i) {
    			$.ajax({
    				url: urlList[i],
                            async: false
    			}).done(function(msg) {
                            $(document).data(urlList[i],true); 
    				checkIndex(urlList, callback, i);
    			});
    			
    		}
    
    		function checkIndex(urlList, callback, i) {
    			if(i+1 == urlList.length) {
    				//$.isFunction(callback) && callback();
    				if(callback != undefined) eval(callback+'();');
    			} else loadRecursive(urlList, callback, i+1);
    		}
    
    		// TEST
    		
    		$(document).ready(function() {
    			loadScripts(new Array('./uno.js'),'f1');
    			loadScripts(new Array('./uno.js','./due.js'),'f2');
    		});
    		
    	</script>
    	
    </body>
    </html>

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved.