Visualizzazione risultati 1 fino 6 di 6

Discussione: slider javascript problema settimeout

  1. #1
    Guest

    Predefinito [RISOLTO] slider javascript problema settimeout

    Ciao ragazzi,

    sto realizzando un semplice slider che cambi le immagini dopo un certo tempo, ma ho un piccolo problema. Ho realizzato un metodo "scorri" che deve cambiare l'immagine, ma quando invoco setTimeout mi da questo errore:

    this.scorri is not a function

    La cosa che non riesco a capire è che il metodo viene eseguito una volta, nel metodo init, e cambia l'immagine. La sua ultima riga contiene il setTimeout e qui ottengo l'errore, dice che
    this.scorri non è una funzione, ma lo ha eseguito. Dove sbaglio? Questo è il codice:

    Codice:
    function slider(id,indirizziFoto) {
    	this.riquadro = null;
    	this.immagini = indirizziFoto;
    	this.link = null; //array che contiene i link di riferimento per ogni immagine dello slider 
    	this.imgAttuale = 0;	//l'indice del riquadro attuale inizializzato a 0, la prima immagine dell'array
    	this.timeout = null;	//timeout per il metodo scorri
    
    	this.init = function() {
    		this.riquadro = document.getElementById(id);
    		this.scorri();
    	};
    
    	this.avanti = function(){
    		if(this.imgAttuale <this.immagini.length-1) {
    			this.imgAttuale += 1;
    			this.riquadro.src = indirizziFoto[this.imgAttuale];
    		}
    	};
    
    	this.indietro = function() {
    		if(this.imgAttuale >0) {
    			this.imgAttuale -= 1;
    			this.riquadro.src = indirizziFoto[this.imgAttuale];
    		}
    	};
    
    	this.scorri = function() {
    		if(this.imgAttuale <this.immagini.length-1) {
    			this.imgAttuale ++;
    			this.riquadro.src = indirizziFoto[this.imgAttuale];
    		}
    		else {
    			this.imgAttuale = 0;
    			this.riquadro.src = indirizziFoto[this.imgAttuale];
    		}
    		this.timeout = setTimeout("this.scorri();",2000);
    	};
    }
    Ultima modifica di TITANUM : 13-04-2013 alle ore 11.29.32

  2. #2
    karl94 non è connesso Staff AV
    Data registrazione
    03-10-2005
    Messaggi
    17,744

    Predefinito

    Togli le virgolette, le parentesi e il punto e virgola, passa solamente un riferimento alla funzione, non una stringa.
    Comunque sarebbe meglio definire i metodi nel prototipo dell'oggetto, non come funzioni assegnate alle varie proprietà di ogni singola istanza.
    Ultima modifica di karl94 : 12-04-2013 alle ore 18.46.41

  3. #3
    Guest

    Predefinito

    Ho modificato il metodo init in questo modo:

    Codice:
    	this.init = function() {
    		this.riquadro = document.getElementById(id);
    		this.timeout = setInterval(this.scorri,2000);
    	};
    Ora la temporizzazione funziona, ho però un altro problema: ad ogni esecuzione del metodo
    quindi ogni due secondi, ottengo questo errore:

    this.riquadro is undefinited

    se non uso la temporizzazione funziona, la variabile viene inizializzata una riga sopra. Il codice html legato alla pagina è questo:

    Codice:
    <html>
    	<head>
    		<script type=text/javascript src=slider.js></script>
    		<script type=text/javascript>
    			immagini = new Array("uno.JPG","due.JPG","tre.JPG");
    			slider = new slider("slider",immagini);
    			
    		</script>
    	</head>
    	<body  onload=slider.init("slider");>
    		<div >
    			<img id=slider src="uno.JPG">
    		</div>
    	</body>
    </html>
    Sapete dirmi qual'è il problema? Grazie

  4. #4
    karl94 non è connesso Staff AV
    Data registrazione
    03-10-2005
    Messaggi
    17,744

    Predefinito

    Questo accade poiché quando la funzione che hai passato a setInterval viene chiamata, l'oggetto this all'interno di questa diventa l'oggetto globale (l'oggetto Window). Devi dunque passare una funzione che agisca in modo indipendente dallo scope (e dunque dall'oggetto this) in cui si trova. Per fare ciò EcmaScript5 ci fornisce pronto il metodo bind, che puoi usare in questo modo:
    Codice:
    this.timeout = setInterval(this.scorri.bind(this), 2000);
    Ma questo è stato introdotto solo di recente, dunque non tutti lo supportano. Il metodo alternativo è costruire una funzione che faccia ciò che bind fa:
    Codice:
    this.timeout = setInterval((function(t){return function(){t.scorri.call(t)}})(this), 2000);

  5. #5
    Guest

    Predefinito

    Funziona!!!

    Ho usato la seconda soluzione per avere maggiore compatibilità.

    Grazie mille

    Avrei un'altra domanda: perché sarebbe meglio definire i metodi nel prototipo nell'oggetto?

  6. #6
    karl94 non è connesso Staff AV
    Data registrazione
    03-10-2005
    Messaggi
    17,744

    Predefinito

    Probabilmente non accede con i moderni motori Javascript, ma nei più vecchi ogni volta che viene creata un'istanza (mediante l'operatore new) di un oggetto slider, vengono reinterpretate le funzioni che lì dichiari ed ad ognuna di queste viene assegnato l'oggetto scope. Se definisci i metodi nel prototipo invece il tutto viene fatto una volta e basta rsiparmiando memoria e preziosi cicli macchina.
    Abbi un po' di riguardo anche per i tuoi visitatori che non posseggono dispositivi dalle prestazioni eccelse (specialmente quelli mobili).

Regole di scrittura

  • Non puoi creare nuove discussioni
  • Non puoi rispondere ai messaggi
  • Non puoi inserire allegati.
  • Non puoi modificare i tuoi messaggi
  •