Kirjautuminen

Haku

Tehtävät

Keskustelu: Nettisivujen teko: JavaScript: monen kuvan preload

punppis [19.05.2009 23:19:23]

#

Yritän ladata JavaScriptillä monta kuvaa etukäteen, mutta en onnistu. Yksittäisen kuvanlatauksen olen saanut toimimaan.

Aluksi tappelin yksittäisen kuvanlatauksen kanssa, sillä en tajunnut, että minun pitää luoda uusi image-objekti. Vanhan img-objektin (html:llä luodun) complete-arvohan on siis alunperin jo true, vaikka src-attribuuttia vaihtaakin (bugi?).

Noh, nyt pitäisi kuitenkin ladata 1-5 kuvaa etukäteen, enkä saa tätä millään toimimaan. Tässä vielä koodi:

HTML:

<div id="kuvat">
	<img src="eka.jpg" alt="" />
	<img src="toka.jpg" alt="" />
	<img src="kolmas.jpg" alt="" />
	<img src="neljas.jpg" alt="" />
	<img src="viides.jpg" alt="" />
</div>
<button onclick="vaihdaSivu()">vaihda kuvat</button>

JavaScript:

var Pyynto;
// Alustetaan Pyynto-muuttuja sopivalla tavalla riippuen käytettävästä selaimesta:
function alustaPyynto() {
	// Jos käytettävä selain on Internet Explorer:
	if(window.ActiveXObject) {
		Pyynto = new ActiveXObject("Microsoft.XMLHTTP");
	}
	// Jos käytettävä selain on jokin muu, esim. Mozilla, Opera, Safari:
	else if(window.XMLHttpRequest) {
		Pyynto = new XMLHttpRequest();
	}
}

// Käytetään GET-muuttujia tiedon välittämiseen palvelimelle
function vaihdaSivu() {
	// !!! NÄYTÄ LOADING TEKSTI !!!

	// Alustetaan ensin Pyynto-muuttuja kutsumalla edellä toteutettua funktiota:
	alustaPyynto();

	// Määritellään funktio, joka suoritetaan, kun vastaus palvelimelta on saapunut:
	Pyynto.onreadystatechange = kasitteleSivunvaihto;

	// Käytetään GET-muuttujia tiedon lähettämiseen asynkronisesti
	// palvelimelle tarkista.php-nimiselle skriptille:
	Pyynto.open("GET", "uudetkuvat.php", true);

	// Lähetetään pyyntö palvelimelle:
	Pyynto.send(null);
}
var kuvat = new Array();
var tmpkuvat;
function kasitteleSivunvaihto() {
	// Tarkistetaan, onko pyyntö suoritettu kokonaan:
	if(Pyynto.readyState == 4) {
		// Tarkistetaan, onko pyynnön suoritus onnistunut:
		if(Pyynto.status == 200) {
			// Jos kaikki on kunnossa, käsitellään saapunut data:

			// Pistetään uusi html-koodi paikalleen
			document.getElementById('kuvat').innerHTML = Pyynto.responseText;

			// Otetaan kaikkien kuvien src talteen
			tmpkuvat = document.getElementById('kuvat').getElementsByTagName('img');
			for(var x=0;x<tmpkuvat.length;x++) {
				// Luodaan jokaisesta kuvasta uusi image-objekti.
				kuvat[x] = new Image();

				// Lisätään juuri luotuun image-objektiin src. Tästä alkaa kuvan lataus selaimen muistiin.
				kuvat[x].src = tmpkuvat[x].src;
			}
			sivunvaihtoLoading();
		}
		else {
			alert("Sivun vaihtamisessa tapahtui virhe!");
		}
	}
}
function sivunvaihtoLoading() {
	var ok = true;
	for(var x=0;x<kuvat.length;x++) { // Käydään kaikki kuvat läpi
		if(!kuvat[x].complete) { // Jos yksikin ei ole ladannut loppuun, niin keskeytetään looppi...
			ok = false;
			break;
		}
	}
	if(!ok) { // ... ja ajetaan funktio uudestaan.
		setTimeout('sivunvaihtoLoading()', 10);
	}
	else {
		// Näytetään juuri ESILADATUT kuvat.
		// !!! POISTA LOADING TEKSTI !!!
	}
}

Koodi ei vain jostain syystä toimi. Heti kun uusi html-koodi on ladattu, selain laittaa uuden html-koodin paikalleen ja loading-teksti katoaa ja käyttäjä näkee kuinka kuvat hiljalleen latautuvat, vaikka niiden pitäisi olla ladattu jo valmiiksi (loading-tekstin ollessa näkyvillä koko ajan).

jlaire [20.05.2009 00:05:33]

#

Vaikea sanoa, mistä ongelma johtuu. Jos näkisi ihan koko koodin tai laittaisit sen jonnekin nettiin ja antaisit linkin, niin voisi testata.

Pelkkä veikkaus, mutta jos kuvien complete-arvo ei toimi oikein kun kuvia ei ole lisätty sivulle, yksi ratkaisu voisi olla lisätä ne sinne heti, mutta asettaa display:none; tmv. ja näyttää vasta, kun lataus on valmis.

var Pyynto;

Miksi tähän käytetään globaalia muuttujaa? Jotkut ovat tätä täällä kehuneet, mutta minulle ei aukea. Muutenkin on vähän turhaa toteuttaa AJAX-kutsua itse, kun kirjastoista (esim. jQuery) löytyy valmiita ja parempia.

setTimeout('sivunvaihtoLoading()', 10);

Mieluummin näin:

setTimeout(sivunvaihtoLoading, 10);

punppis [20.05.2009 03:04:31]

#

funktio kirjoitti:

Muutenkin on vähän turhaa toteuttaa AJAX-kutsua itse, kun kirjastoista (esim. jQuery) löytyy valmiita ja parempia.

Jonkun tarvitsee tehdä se jQuery, ennenkuin sitä voi muut käyttää. Pointtini on siis uusien asioiden oppiminen. Olisin ihan hyvin voinut hakea jonkun valmiin skriptin internetistä.

var Pyynto on globaali, koska sitä käytetään kahdessa eri funktiossa.

Jos lisäisin aina edellisen ja seuraavan sivullisen kuvia ladattavaksi, niin lisäisi palvelimen liikennöintimääriä (jotka on siis rajoitettu) liikaa.

Kuten sanottu, myös tuo complete-arvo toimii ihan hyvin tuoll systeemillä yhden kuvan kanssa.

Eipä ollutkaan vika tuossa koodissa, vaan jossain muuaalla... Eli problem solved.

jlaire [20.05.2009 03:38:18]

#

punppis kirjoitti:

Jonkun tarvitsee tehdä se jQuery, ennenkuin sitä voi muut käyttää. Pointtini on siis uusien asioiden oppiminen.

Joo, se on ihan hyvä toteuttaa kerran itse. Mutta sitten kun ymmärtää sen toiminnan, en nää syytä oman viritelmän käyttämiseen jonkun valmiin ja huolella tehdyn toteutuksen sijaan (ellei se oma ole parempi).

punppis kirjoitti:

var Pyynto on globaali, koska sitä käytetään kahdessa eri funktiossa.

Ok. Itselläni on tapana käyttää parametreja ja paluuarvoja.

punppis kirjoitti:

Kuten sanottu, myös tuo complete-arvo toimii ihan hyvin tuoll systeemillä yhden kuvan kanssa.

Jep, mutta kun en millään keksinyt, mitä muuta tuossa koodissa voisi olla vikana.

Vastaus

Aihe on jo aika vanha, joten et voi enää vastata siihen.

Tietoa sivustosta