Visualizzazione dei risultati da 1 a 5 su 5
  1. #1

    Javascript - setInterval impalla il computer

    Salve ragazzi come da titolo ho un problema con uno script Javascript, sto realizzando un sito che nella testata ha un riquadro dove scorrono 6 immagini per volta.
    Lo script in questione è questo:
    codice:
    var array_immagini = new Array();
    
    
    function change_img_riquadro(id){
        //conto lunghezza array
        var n_img = array_immagini.length;
        
        //scelgo un numero casuale da 0 a n_img-1
        n_img--;
        var i = Math.round(n_img * Math.random());
        
        //catturo riquadro
        var riquadro = window.document.getElementById(id);
        riquadro.style.backgroundImage = "url('" + array_immagini[i] + "')";
        
        //intervallo funzione 7secondi
        window.setInterval(function(){change_img_riquadro(id); }, 7000);
    }
    Le immagini che passo al riquadro vengono ripescate dalla photogallery e ridimensionate a 922x321 px (la dimensione precisa del riquadro) tramite PHP. Sempre da php genero l'array di immagini e poi chiamo la funzione change_img_riquadro passandogli l'ID del DIV dove dovranno scorrere.

    Come vedete è molto semplice tutta via se lascio il sito 'fermo' per qualche minuto poi si impalla tutto. Secondo voi qual'è il problema?
    Per ora i vari test che ho condotto sono tutti in locale (uso server XAMPP), non so se in ambiente reale darà gli stessi problemi però prima di pubblicare volevo chiarirmi bene le idee e preparare un eventuale "piano B". Grazie in anticipo per le risposte!

  2. #2
    Moderatore di CSS L'avatar di KillerWorm
    Registrato dal
    Apr 2004
    Messaggi
    5,771
    Ciao, molto semplice. Avendo chiaro il funzionamento del setInterval non è difficile capire il problema. Anzi è più difficile spiegarlo che capirlo.
    In parole semplici, quando viene letto il setInterval, viene creata una sua istanza (diciamo così) che "attiva" una ripetizione ad intervalli regolari in modo da richiamare periodicamente una specifica funzione.
    Dal momento che hai messo il setInterval dentro la stessa funzione che viene da questo richiamata, succede che ogni volta che viene eseguita tale funzione verrà letto anche il setInterval che va a creare, di volta in volta, una sua nuova istanza.
    Si può intuire quindi che ogni 7 secondi vengono raddopiate in modo esponenziale le istanze create col setInterval, le quali richiamano a loro volta la stessa funzione.
    In teoria dopo circa un minuto quello script starà cercando di eseguire 512 volte, allo stesso momento, quella stessa funzione.. e sette secondi dopo saranno 1024 volte. Puoi capire quindi il motivo del crash.

    Puoi risolvere in vari modi. Normalmente il setInterval dovresti metterlo fuori dalla funzione o usare in qualche modo un clearInterval, ma per farla semplice ti consiglierei di usare un setTimeout anziché il setInterval.
    Questo funziona in maniera molto simile con la sola differenza che la funzione specificata sarà richiamata una sola volta dal momento che viene letto. In pratica è un semplice timer.
    codice:
        setTimeout(function(){change_img_riquadro(id); }, 7000);
    E' chiaro che la ripetizione ciclica avverrà proprio perché ogni 7 secondi verrà letto nuovamente quel timer, essendo messo dentro la tua funzione.
    Installa Forum HTML.it Toolset per una fruizione ottimale del Forum

  3. #3
    Ciao KillerWorm e grazie per la risposta, finalmente ho capito che ragionamento c'è dietro a queste 2 funzioni! Te ne sono davvero grato (:
    comunque pongo subito un'altra domanda: ho modificato il codice e sembrava funzionare ma in realtà non è proprio così..
    in pratica quando il sito viene lasciato in "background" (della serie - apro un'altra scheda per qualche min - ) sia con la setInterval che con la setTimeout è come se lo script si "fermasse" e quando ritorno nella scheda del sito il riquadro comincia a cambiare 5 foto al secondo e se non chiudo crasha.. è come se quando apro un'altra scheda (o riduco ad icona il browser) lo script si "addormentasse" e quando riapro la scheda si sveglia di botto e comincia a schizzare, sai dirmi come mai fa così? ed in caso come posso risolvere?
    grazie!

  4. #4
    finalmente ho risolto:
    codice:
    function change_img_riquadro(id){
    	//intervallo funzione 7secondi
    	window.setInterval(function(){change2(id); }, 7000);
    }
    function change2(id){
    	//conto lunghezza array
    	var n_img = array_immagini.length;
    	
    	//scelgo un numero casuale da 0 a n_img-1
    	n_img--;
    	var i = Math.round(n_img * Math.random());
    	
    	//catturo riquadro
    	var riquadro = window.document.getElementById(id);
    	riquadro.style.backgroundImage = "url('" + array_immagini[i] + "')";
    }
    in questa maniera non si blocca e continua anche "in background" (:

    comunque, per puro interesse lascio aperta la mia domanda di prima - anzi mi sono fatto una mia teoria personale e vorrei sapere che ne pensi:
    secondo me anche con setTimeout crea sempre una nuova istanza e questo perchè la funzione non ha mai un "return" quindi è come se fosse una chiamata ricorsiva infinita e quindi ogni volta che ri-chiama la funzione in realtà lascia in sospeso quella appena chiamata .. plausibile?

  5. #5
    Moderatore di CSS L'avatar di KillerWorm
    Registrato dal
    Apr 2004
    Messaggi
    5,771
    Bene per il nuovo script, è una valida soluzione.

    Riguardo l'altro problema che indichi, ho fatto giusto qualche prova al volo su alcuni browser ma personalmente non lo riscontro.
    Il tutto mi funziona regolarmente con setTimeout, andando su altre schede e poi tornando su quella o chiudendo a icona la finestra e poi riaprendo. Nessun accavallamento di intervalli e nessun crash.
    Riguardo la mancanza del "return" non vedo alcuna connessione con quel tipo di problema. A mio personale parere è più plausibile che ci sia qualche altra chiamata di quella funzione, "nascosta" da qualche parte sul tuo documento, che magari ti sfugge, o un qualche problema di logica del funzionamento nel resto del tuo codice (che non hai postato), o ancora, puoi aver fatto semplicemente confusione durante i test mentre cambiavi lo script e magari non ti sei accorto che stavi andando a riattivare la pagina col vecchio script... ma ovviamente sono tutte ipotesi. Nel caso sarebbe opportuno vedere la pagina per intero per capire esattamente il problema.

    Ad ogni modo è buono che tu abbia risolto in qualche modo.
    Installa Forum HTML.it Toolset per una fruizione ottimale del Forum

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.