[javascript] ImageCache

0

Witam, od jakiegos czasu szukam sposobu na ladowanie graficznych backgroundow zanim wyswietlona zostanie cala strona. znalalzlem w sieci cos takiego jak "ImageCache", z tym ze nie bardzo moge dojsc do tego jak to nalezy zastosowac, pomijam fakt, ze nie jestem tez ani biegly z JS ani z angielskiego, miedzy wierszami wyczytuje.. :P [url=http://alexrabarts.github.com/jquery-cacheimage]tutaj zamieszczam stronke [/url], do tego zalaczam kod zrodlowy ktory obecnie samodzielnei maltretuje. przy pomocy "hover" sprawdzam czy drugi obrazek faktycznie siedzi juz w pamieci ale niestety - zanim obrazki zostana zmienione nastepuje wczytanie tego ktory chcialbym aby juz siedzial w pamieci...
bardzo proszę o jakaś pomoc, ewentualnie przetlumaczenie na chlopski rozum skladni tej funkcji ImageCache, bo od 3 dni tkwie w miejscu pt "ladowanie grafiki do pamieci"..

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="Content-type" content="text/html; charset=ISO-8859-2">
<title>Dokument bez nazwy</title>

<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="http://plugins.jquery.com/files/jquery.cacheimage.js.txt"></script>

<style type="text/css">
* { margin: 0 auto; padding: 0;}
#obraz { background-image:url(Obraz1.jpg); display: block; height: 800px; width: 600px;}
#obraz:hover {background-image:url(Obraz11.jpg);} </style>

<script type="text/javascript"> 
function dodajZdarzenie(odnosnik, zdarzenie, funkcja){
	if (odnosnik.addEventListener) {
		odnosnik.addEventListener(zdarzenie, funkcja, false); 
	}
	else { 
		odnosnik.attachEvent("on"+zdarzenie, funkcja); 
	}
}



	var obrazki = [
				   'obraz1.jpg',
				   'obraz11.jpg',
				   //'obraz2.jpg',
				   //'obraz3.jpg',
				  // 'obraz4.jpg',
				  // 'obraz5.jpg',
				  // 'obraz6.jpg',
				 //  'obraz7.jpg',
				 //  'obraz8.jpg',
				   ];

function Laduj () {
	for(x=0; x< obrazki.length; x++) {
		   $.cacheImage(obrazki[x])
	alert(obrazki[x])
	}
}

dodajZdarzenie(window, 'load', Laduj)
</script>

</head>

<body>
<div id="obraz"></div>
</body>
</html>
0

Z tego co widzę, to ImageCache jest takim rozszerzeniem prostej metody:

new Image().src = "adres_obrazka.jpg";

Kod wyżej tworzy obiekt klasy Image, któremu od razu przypisywana jest wartość src - link do obrazka. Przeglądarka od razu wczytuje obrazek.
Spróbuj zrobić tak:

var obrazki = [...];
for(var x=0; x< obrazki.length; x++) {
   var obrazek = new Image();
   obrazek.src = obrazki[x];
}

I to umieść w zdarzeniu DOMContentLoaded (wykonywane wcześniej niż OnLoad). Używasz, jQuery, więc będzie to tak:

$.ready(function() {
  for(...) { var obrazek ...  }
});
0

@DewREW:
Nie bardzo rozumiem w czym masz problem. Jeśli od razu chcesz zcache'ować obrazki, to nie musisz stosować żadnego onload. Nie musisz cache'ować obrazków pojedynczo. Gdy ścieżki do obrazków masz w tablicy obrazki, to wywołaj po prostu:

$.cacheImage(obrazki);

Tak naprawdę to jest spora szansa, że w ogóle nie musisz tego używać. Ja zamiast tego używam zwykle techniki zwanej sprite'ami CSS (ang. css sprites). Możesz o tym pogooglać.

Niestety, programista bez angielskiego jest jak bez ręki. Z tą różnicą, że może coś zrobić, by ten stan rzeczy zmienić. Istnieją doskonałe artykuły odnośnie sprite'ów CSS, ale po angielsku. Po polsku nie będę żadnego polecał, bo nie ręczę za twórców, których nie znam. Poza tym angol jest niezbędny do czytania dokumentacji.

Podobno każdy programista, by zachować jasność umysłu, powinien raz na jakiś czas opanować nowy język. Chodzi o język programowania, ale Tobie na pierwszy ogień polecam... angielski. Poważnie. Nie może być sytuacji, że nie rozumiesz dokumentacji i prosisz ludzi na forach, żeby Ci to wytłumaczyli. To kompletnie nie pasuje do profesjonalnego programisty.

0

to
$.cacheImage(obrazki);
w ogóle nie łapie. przy podmianie obrazkow i tak nastepuje przerwa i na pasku pisze "pobieranie pliku xyz". ale dzieki za szybką reakcję. do cache'owania wrócę rano bo teraz juz nie mam sily ale chyba postaram się to zrobić tak jak napisał @kubARek, zobacze co z tego wyjdzie, póki co chcąc uzyć DOMContentLoaded (nie działa pod IE), musialem skorzystać ze skryptu 'documentReady' pobranego stąd i pojawila się pewna niejasność. funkcja wywolana przez documentReady łapie dwukrotnie i pojawia sie na dole tekst "DOM Loaded".. dlaczego?

var obrazki = [
				   'obraz1.jpg',
				   'obraz11.jpg',
				   //'obraz2.jpg',
				   //'obraz3.jpg',
				  // 'obraz4.jpg',
				  // 'obraz5.jpg',
				  // 'obraz6.jpg',
				 //  'obraz7.jpg',
				 //  'obraz8.jpg',
				   ];

function Laduj () {
	for(x=0; x< obrazki.length; x++) {
		   $.cacheImage(obrazki[x])
	alert(obrazki[x])
	}
}

documentReady(Laduj);
</script>
</head>
<body>
<div id="obraz"></div>
</body>
</html>

PS. jQuery jeszcze nie kapuje, na razie do tego problemu staram sie wykorzystac, także jak nie trzeba to czysta javascript do mnie :P

0

Ale po co robisz to DOM Loaded? Po co Ci to? Co się stanie złego jeśli to wywalisz i po prostu odpalisz Laduj()?

Z tego co widzę w kodzie to cacheImage(obrazki) powinno dać taki sam efekt jak cacheImage(obrazki[x]) w pętli.

PS. W tablicy obrazki nie zostawiaj przecinka za ostatnim (niezakomentowanym) elementem. IE tego nie lubi.

0

bo to jest moj poczatek do preloadera. dlatego DOM Loaded, chcę żeby wywolal funkcje preloadera, tzn podczas ladowania tych obrazków animował sie jakis gifek i pojawiał się procent zaladowania, po zaladowaniu wszystkich bede chcial lagodnie ukryc preloader a pokazac zawartosc strony. chcialbym tez zeby preloader pokazywal sie tylko wtedy gdy obrazkow nie bedzie w pamieci podrecznej przegladarki, a nie za kazdym razem (takie preloadery znajdywalem w sieci, zreszta nie chce za bardzo zrzynać, wolalbym cos po swojemu.. znalazlem jeden ciekawy, ale zachowywal sie anomalnie pod opera, moze wrzuce jego skrypt ale pozniej, nie chce za bardzo mieszac w jednym temacie) dlatego wazne jest dla mnie zeby to ladowanie dzialalo poprawnie. mozliwe ze zle sie za to wszystko zabieram ale jestem na poczatku drogi, na razie mam taki pomysl i taki oto problem: 'jak wczytac wskazane pliki bedace backgroundami bloków do pamieci, zanim strona zostanei wyswietlona'

w dalszym ciagu nie wiem dlaczego documentReady powoduje dwukrotne wyswietlanie 2x alert. i jeszcze ten napis na dole "dom loaded" :|

0

i jeszcze ten napis na dole "dom loaded"
A to kod w pliku documentReady.js:

function init() {
	if (arguments.callee.done) { return; }
	arguments.callee.done = true;
	//your code:
	document.body.appendChild(document.createTextNode('DOM loaded.')); //// <--- tu, o; tę linijkę możesz wywalić
};

I teraz pytanie, dlaczego dwa razy? Otóż, funkcja poprawnie wywołuje się w momencie DOMContentLoaded, ale w documentReady.js znalazłem taki kwiatek: window.onload = callback;Dzięki temu callback dodawany jest zarówno do DCL, jak i onLoad, co powoduje dwukrotne jej wywołanie :) Żeby to naprawić, po prostu usuń w/w linijkę. Albo dodaj do funkcji Laduj() dwie początkowe linijki kodu, jakie są w funkcji init(). Obiekt arguments.callee w kontekście funkcji jest właśnie daną funkcją :P Czyli w tym przypadku arguments.callee === init. We wnętrzu funkcji Laduj(), arguments.callee będzie samą funkcją Laduj.

0

@DewREW:
Weź wywal cały ten skrypt documentReady. Skoro @kubARek znalazł w nim takie coś, to cholera wie co tam jeszcze siedzi. Jeśli sam nie masz wiedzy odpowiedniej do debugowania czy choćby rozpoznania, czy jakiś skrypt jest OK, to korzystaj z jak najmniejszej liczby skryptów -- ale takich, o których wiesz na pewno, że działają. jQuery do nich należy. I już o go używasz, prawda? Nie ma najmniejszego sensu dodawanie kolejnego skryptu, który dublowałby działanie innego, który już masz dodany do strony. jQuery ma potrzebą funkcjonalność, więc z niej skorzystaj, a nie zwiększaj rozmiaru strony kolejnym badziewiem.

W jQuery osiągniesz pożądany efekt w ten sposób:

$(document).ready(Laduj);

Chyba że poradzisz sobie innymi, specjalistycznymi, mniejszymi skryptami. I będziesz mógł usunąć jQuery. Wtedy to zrób -- jQuery zajmuje parędziesiąt KB i jeśli potrzebujesz np. samego ready(), to nie opłaca się go używać. Korzystasz też z wtyczki do jQuery o nazwie imageCache, ale to też mała wtyczka -- możesz napisać jej odpowiednik samodzielnie, zgodnie z radami kubARka. Wtedy będziesz mógł wywalić jQuery. Ale jeśli chcesz tę bibliotekę zostawić, to wykorzystaj ją w maksymalnym stopniu.

edit: Wracając do tego skryptu documentReady. Dopiero teraz na niego spojrzałem. Jest napisany przez Piotrka Petrusa. Nie powinien więc być lipny, czy nie działający. Wątpię, by Piotrek wypuścił jakiś badziew. Jak będę miał chwilę, to przeanalizuje co jest nie tak i dlaczego. Niemniej jednak to, co napisałem, pozostaje słuszne: skoro masz jQuery, to nie dodawaj kolejnego skryptu, tylko użyj funkcji z jQuery tam gdzie to możliwe.

0

wyglada na to ze w skrypcie dotyczacym documentReady, ostatnie linie kodu, tj.

function init() {
        if (arguments.callee.done) { return; }
        arguments.callee.done = true;
        //your code:
        document.body.appendChild(document.createTextNode('DOM loaded.')); //// <--- tu, o; tę linijkę możesz wywalić
};

documentReady(init);

są przykladem korzystania z tego skryptu :) bez tych ostatnich linii chyba działa jak dzialac powinno.

wracajac do mojego dokumentu, ktory w tej chwili dokument wyglada tak:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="Content-type" content="text/html; charset=ISO-8859-2">
<title>Dokument bez nazwy</title>
<!--[if IE]><link rel="stylesheet" type="text/css" href="css.css" /><![endif]-->
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="document.ready.js"></script>


<style type="text/css">
* { margin: 0 auto; padding: 0;}
#obraz { background-image:url(Obraz1.jpg); display: block; height: 800px; width: 600px;}
#obraz:hover {background-image:url(Obraz2.jpg);} </style>

<script type="text/javascript"> 
function dodajZdarzenie(odnosnik, zdarzenie, funkcja){
	if (odnosnik.addEventListener) {
		odnosnik.addEventListener(zdarzenie, funkcja, false); 
	}
	else { 
		odnosnik.attachEvent("on"+zdarzenie, funkcja); 
	}
}


function zmien () {

document.getElementById('obraz').style['backgroundImage'] = "url(Obraz2.jpg)";
}

	var nazwy = [
				   'Obraz1.jpg',
				   'Obraz11.jpg',
				   'Obraz2.jpg',
				   'Obraz3.jpg',
				   'Obraz4.jpg'
				  // 'obraz5.jpg',
				  // 'obraz6.jpg',
				 //  'obraz7.jpg',
				 //  'obraz8.jpg'
				   ];
	var obrazki = [];
	var ilosczaladowanych = 0;
	var postep = 0;
	
function Laduj () {
	if (arguments.callee.done) { return; }
	arguments.callee.done = true;
	for(var x=0; x< nazwy.length; x++) {
   	obrazki[x] = new Image();
   	obrazki[x].src = nazwy[x];
	ilosczaladowanych++;
	postep = Math.round(ilosczaladowanych*100/nazwy.length)+"%";
	alert(postep);
	if (postep == "100%") {
	//document.getElementById('obraz').style['backgroundImage'] = "url(Obraz2.jpg)";
	}
	}
	
//dodajZdarzenie(document.getElementById('obraz'),'mouseover', zmien);
}



documentReady(Laduj);
</script>
</head>

<body>
<div id="obraz"></div>
</body>
</html>

zmienilem sposob ladowania obrazków tak jak podał @kubARek. ale czy to na pewno działa? jezeli zmieniac tło przez druga funkcje z zapisem 'document.getElementById('obraz').style['backgroundImage'] = "url(Obraz2.jpg)";' w FF wyglada to calkiem dobrze, ale np gdy robie to przez "hover" wydaje mi sie ze przerwa przy podmianie obrazków nadal wystepuje. z kolei w IE6, caly skrypt interpretowany jest poprawnie ale co z tego skoro przy kazdej mozliwej podmianie obrazków jest oczekiwanie na jego wczytanie, mimo ze skrypt mial je zaladowac do pamieci. jest jakiś sposób pozwalający jednoznacznie stwierdzić że wskazane pliki na pewno są już załadaowane do pamięci? moglby ktorys z panów sprawdzic jak to prezentuje sie u niego? bo moze tylko mnie sie wydaje ze coś jest nie tak..

0

Sprawdziłem ten kod, z małym wyjątkiem. Zamiast documentReady(Laduj); dałem po prostu Laduj();

W Firefoxie, po sprawdzeniu Firebugiem* - najechanie na

zmienia obrazek, nie pobierając go przy tej zmianie. Czyli tak jak być powinno.
Pod IE8 podobnie, nie widać, żeby się obrazek ładował.. Jeśli chodzi o IE6, to jeśli naprawdę nie musisz, to nie przejmuj się dziwactwami tej przeglądarki, gdyż na szczęście odchodzi w niebyt :)</p>

*zainstaluj i sam zobaczysz, świetna sprawa z tym dodatkiem :) Zakładka Net mówi o tym, jakie pliki są aktualnie ściągane, ile czasu zajęło, jaki rozmiar, etc.

0

Sprawdziłem ten kod riddle'a. Niestety muszę przyznać, że to nie jest najlepszy kod, jaki napisał Piotrek (webdeveloper, którego doceniam i szanuję).

Faktycznie, nie ma gwarancji, że funkcja podana jako parametr documentReady zostanie wywołana raz. Zamiast tego, funkcja ta wymaga zastosowania się do takiej konwencji:

function Laduj() {
	// te dwie linijki musisz dopisać do każdej funkcji
        // przekazywanej do documentReady
	if (arguments.callee.done) { return; }
	arguments.callee.done = true;

        // dopiero tu umieszczasz kod właściwy
        // z funkcji Laduj()
        tu_kod_wykonujący_właściwe_ładowanie(); // *
};

documentReady(Laduj);

Nie znam kontekstu powstania tego skryptu. Może Piotrek bardzo wyraźnie ostrzegał, że działa to właśnie tak. Niemniej jednak patrząc na to tak, jak to wygląda, uważam tę cechę kodu za totalny suchar, niewygodny w użyciu i niepotrzebnie polegający na tym, by ktoś pamiętał o dodaniu tych dwóch linijek. Może nawet napiszę do Piotrka w tej sprawie mail wraz z propozycją naprawienia kodu. Kod jest stary i może dzisiaj Piotrek już by tego tak nie napisał, ale skoro ludzie do dziś tego używają i mają z tym problemy, to chyba warto dać mu znać.

0

documentReady przydaje się, przynajmniej mi, z tego wzgledu ze nie musze sam pisac odpowiednika DOMContentLoaded dla każdej z przegladarek

Okej, chyba masz racje, powinno działac.. idąc dalej w las.. jak teraz zrobic zeby to ladowanie odbywalo sie tylko raz (i ponownie przy kazdym czyszczeniu cache przegladarki). po prostu gdy ktos juz ma zaladowane obrazki to wyswietla mu sie Od razu normalna strona glowna. preloader ma byc tylko dla tych co grafiki w cache nie posiadaja. myslałem zeby rozwiazac to poprzez dodanie do poprzedniego kodu

	for(var x=0; x< nazwy.length; x++) {
	if (obrazki[x].src) { break; }
else {
   	obrazki[x] = new Image();
   	obrazki[x].src = nazwy[x];
.
.
.

tzn jezeli tablica obrazki[] zawiera juz jakies wpisy to przerwij dalsze wykonywanie funkcji, a jezeli tablica jest pusta to dopiero zaladuj pliki.. ale chyba nie tedy droga bo to mi nie nie dziala..

0

To już od przeglądarki zależy. Jak ktoś ma załadowane obrazki w keszu, to przeglądarka wczytuje je z keszu, a jak nie ma, to pobiera z serwera ;)

Co do kodu wyżej. Odświeżając stronę, tracisz dane na temat tego, co zrobił skrypt JS. Czyli np. jeśli masz tablicę obrazki, na początku pustą, potem w trakcie preloadowania ją wypełniasz obrazkami, to po odświeżeniu, tablica ta nie będzie wypełniona, tylko znów pusta.

0

a mozna jakos odwolac sie do cache przegladarki i tam "sprawdzic" czy sa te pliki? ;>

i dalej.. problem zapewne banalny ale z jQuery mam stycznosc dzien z noca, tak wiec proszę wybaczyc. chce zeby jeden blok zanikał (#loader). od momentu gdy zniknie, chce zeby zaczał sie pojawiac inny blok(#content). napisałem takie cos, ale te funkcje przebiegaja równoczenie, a nie tak sobie to wyobrazam :) musze przyznac ze troche na chybił/trafił używam tych metod "hide" "show", bo jeszcze sie w tym nie orientuje :) wczesniej próbowałem to zrobic przy pomocy faceOut/fadeIn ale efekt wlasciwie jest ten, sam, równiez działo sie to rownoczesnie.
do tego jeszcze jest jeden blok (#pasek), który chciałbym aby sie schowal ale przez "clip" (ta linijka kodu nie dziala w ogole, nie wiem czemu)
takze.. prosze o poprawki :)

function Laduj () {
	if (arguments.callee.done) { return; }
	arguments.callee.done = true;
	$('#content').hide();
	for(var x=0; x< nazwy.length; x++) {
   	obrazki[x] = new Image();
   	obrazki[x].src = nazwy[x];
	ilosczaladowanych++;
	postep = Math.round(ilosczaladowanych*100/nazwy.length)+"%";
	alert(postep);
	if (postep == "100%") {
	$('#loader').animate({ opacity: 0 },5000);
	$('#pasek').hide( "clip", {direction: "vertical"}, 3000);
	$('#content').hide().animate({"opacity": "show"}, {duration: 6000 });

	//document.getElementById('obraz').style['backgroundImage'] = "url(Obraz2.jpg)";

	}
	}
0

a mozna jakos odwolac sie do cache przegladarki i tam "sprawdzic" czy sa te pliki? ;>
Ja nie wiem, może bswierczynski coś więcej powie ;)

chce zeby jeden blok zanikał (#loader). od momentu gdy zniknie, chce zeby zaczał sie pojawiac inny blok(#content)

Zajrzałem na http://api.jquery.com/show/ i http://api.jquery.com/hide i powstało takie coś:

$('#loader').hide(1000, function() {
  $("#content").show(500);
});

jQuery to potęga :)
Najpierw ukrywa element o id=loader, robi to powoli w czasie 1 sekundy (1000 milisekund). W momencie gdy skończy się to całe ukrywanie, wywołuje się funkcja, callback, która ma instrukcję pojawienia elementu o id=content, przez pół sekundy.

0
  1. kod ma się tak:
function Laduj () {
	if (arguments.callee.done) { return; }
	arguments.callee.done = true;
	$('#logo').css({'visibility' : 'hidden'});
	$('#content').hide();  
	for(var x=0; x< nazwy.length; x++) {
   	obrazki[x] = new Image();
   	obrazki[x].src = nazwy[x];
	ilosczaladowanych++;
	postep = Math.round(ilosczaladowanych*100/nazwy.length)+"%";
	if (postep == "100%") {
    $("#pasek").hide("blind", { direction: "vertical" }, 1000);  
	$('#loader').fadeOut(5000, function() {
											$('#content').fadeIn(5000, function () {
														  							 $('#logo').css({'visibility' : 'visible'});
																				 })							 
										  }
						)
	}
	}
	
//dodajZdarzenie(document.getElementById('obraz'),'mouseover', zmien);
}

wszystko działa jak na razie tego bym chcial, poza jedna linijka:
$("#pasek").hide("blind", { direction: "vertical" }, 1000);
ten kod jest na zywca zerzniety ze strny jQuery, zmienilem tylko identyfikator.. a jednak nie dziala. w konsoli firefoxa wywala blad:

Błąd: c.easing[this.options.specialEasing && this.options.specialEasing[this.prop] || a] is not a function
Plik źródłowy: file:///E:/jquery.js
Wiersz: 143

wiadomo co moze byc problemem?

  1. jest jakis niezawodny sposób na rozpoznanie przegladarki IE6? chcialbym dla IE6 w ogole pominąc tego loadera.

3.w jquery mozna w jakis sposob pobrac rozmiar obrazka w kB?

0
DewREW napisał(a)

documentReady przydaje się, przynajmniej mi, z tego wzgledu ze nie musze sam pisac odpowiednika DOMContentLoaded dla każdej z przegladarek

Nie wiem czy zjarzyłeś o co mi w ogóle chodziło. Mówiłem, żebyś olał to documentReady i stosował jego odpowiednik w jQuery, bo już i tak masz dołączone jQuery. Po cholerę Ci dwa skrypty robiące to samo? jQuery potrafi zrobić to, co robi documentReady!

DewREW napisał(a)

Ten kod jest na zywca zerzniety ze strny jQuery, zmienilem tylko identyfikator.. a jednak nie dziala.

Zarzuć no tym linkiem do dokumentacji. Ja w dokumentacji API w ogóle nie widzę takiego wywołania hide, jakie Ty stosujesz (patrzę tutaj).

0

Zarzuć no tym linkiem do dokumentacji. Ja w dokumentacji API w ogóle nie widzę takiego wywołania hide, jakie Ty stosujesz (patrzę tutaj).

hmm sugerowałem się tym

w ogole mam wciaz zastrzezeniaco do ladowania tych plików do pamieci przegladarki.. w tabeli obrazków podałem siezke do pliku majacego 200mb (zmienilem rozszerzenie na .jpg) i preloader Od razu znika po zaladowaniu strony, mimo ze na pasku w przegladarce widac wyraznie ze cos jest wczytywane. ta metoda z przypisaniem 'src' do obiektu new Image, powoduje przypisanie samej sciezki, a nie zaladowania fizycznie pliku do pamieci.. ten loader w ogole nie czeka az pliki zostana wczytane, tylko wyswietla sie na moment (bo tyle mu trzeba by uzupelnic src w tabeli) zeby zaraz zniknac.. chcialbym juz moc pojsc dalej ale nie moge tego ta zostawic :-/ jak to rozwiazac?

0

Obrazki mają jeszcze atrybut onload, którego nazwa mówi wszystko. Przypiszesz funkcję, która będzie sprawdzać, czy wszystkie obrazki się załadowały, jeśli tak, to ukrywasz loadera i pokazujesz stronkę.

0

yhm. ale jak to zastosowac w praktyce? jak to jest "sprawdzic czy się załadowały"?

<script type="text/javascript">                                                                                                 

var nazwy = [
				   'grafika/1.png',
				   'grafika/2.png',
				   'grafika/3.png',
				   'grafika/1.gif',
				   'SF_CDA_NonNet_Full_Win_WW_130_140.jpg'
				  //'obraz6.jpg',
				// 'obraz7.jpg',
				// 'obraz8.jpg'
				   ];
	var obrazki = [];
	var ilosczaladowanych = 0;
	var postep = 0;
	
function Laduj () {
	$('#logo').css({'visibility' : 'hidden'});
	$('#content').hide();  
	for(var x=0; x< nazwy.length; x++) {
   	obrazki[x] = new Image();
	obrazki[x].src = nazwy[x];
	obrazki[x].onload;
	if(obrazki[x].onload) {
	alert('zaladowany');
	}
	ilosczaladowanych++;
	postep = Math.round(ilosczaladowanych*100/nazwy.length)+"%";
	$('#procent').text(postep);
	if (postep == "100%") {
		$('#pasek').slideToggle(5000);
		$('#loader').fadeOut(5000, function() {
											$('#content').fadeIn(5000, function () {
														  							 $('#logo').css({'visibility' : 'visible'});
																				 })							 
										  }
						);
	}
	}
	
}



$(document).ready(Laduj);
</script>

jak widać ja patologicznie napisałem tak:

	obrazki[x].onload;
	if(obrazki[x].onload) {
	alert('zaladowany');
	}

i nie działa, zreszta nie spodziewałbym się że przy takim zapisie mogłoby działac..
jak przy pomocy "onload" mam sprawdzić stan zaladowania obrazka?

0

@DewREW:
Pod własność o nazwie onXXX podstawia się funkcję obsługi zdarzenia XXX zachodzącego na danym obiekcie. "onload" (on load) to zdarzenie load.

Robisz to tak:

obrazek[x].onload = function() {
  alert('Obrazek załadowany!');
};

Działa to tak, że funkcja podstawiona do własności onload obrazka zostanie automatycznie wywołana przez przeglądarkę w momencie załadowania tego obrazka.

Niestety, w powyższym kodzie mamy już ciut bardziej zaawansowane cechy JavaScriptu. Funkcje anonimowe i domknięcia. Jest spora szansa, że sprawi Ci to problemy, jeśli nie znasz JavaScriptu za dobrze.

Może unikniesz tych problemów, jeśli zrobisz to jakoś tak:

obrazek[x].onload = function() {
  ilosczaladowanych++;
  // tu przenieś resztę kodu obsługujących załadowanie jednego obrazka
};
0

@bswierczynski, ech troche pokombinowalem i faktycznie dzieja mi sie jakies anomalia.. typu licznik "ilosczaladowanych" liczy w dziwny sposob, wstawienie np alert('blabla'); sprawia iz funkcja w ogole nie dziala albo dziala jezezli np licznikowi przypisze "0", czy wyswietlanie informacji ze obiekt "obrazki" nie jest zdefiniowany :o takze z moim obecnym stanem wiedzy zgubilem wszelka logike.. powrocilem do pierwotnego stanu (tego co powyzej) i zalaczam tutaj te pliki. gdybys miał chwilke prosiłbym byś u siebie to odpalil i zerknał "do srodka"..

0

Taki gotowiec z głowy pisany :)

var obrazkiDoZaladowania = ['img1.jpg', 'img2.jpg'], obrazkiZaladowane = 0;
for (var i = 0; i < obrazkiDoZaladowania.length; i++) {
  var obrazek = new Image();

  // dodaj zdarzenie onload do tego obrazka
  obrazek.onload = function() {
    obrazkiZaladowane += 1;
    
   // jeśli licznik pokazuje, że zostały załadowane wszystkie zdjęcia
    if (obrazkiZaladowane == obrazkiDoZaladowania.length)
      koniecLadowania();
  }
  // przypisz link, w tym momencie obrazek zacznie się ładować, jak skończy, zostanie wywołana funkcja onload
  obrazek.src = obrazkiDoZaladowania[i];
}

var koniecLadowania = function() {
  $("#loader").hide(500, function() {
    $("#content").show(500);
  });
};
0

pozmienialem wedlug Twojego schematu i beznadzieja. w Firefoxie wydaje sie przebiega wszystko sprawie ale w Operze oraz IE nie. staje na "60%", tak jakby w tym momencie przestal sie zwiekszac licznik. w tym poprzednio co pisałem samodzielnie stawał przy "80%" i tez nic sie dalej nie dzialo.

<script type="text/javascript">                                                                                                 


var nazwy = [
				   'grafika/1.png',
				   'grafika/2.png',
				   'grafika/3.png',
				   'grafika/logo.gif',
				   'SF_CDA_NonNet_Full_Win_WW_130_140.jpg'
				  //'obraz6.jpg',
				// 'obraz7.jpg',
				// 'obraz8.jpg'
				   ];
	

	
	
function koniecLadowania() {	
			$('#pasek').slideToggle(5000);
			$('#loader').fadeOut(5000, function() {
												$('#content').fadeIn(5000, function () {
														  							 $('#logo').css({'visibility' : 'visible'});
																	})							 
								});
	
}
	
function Laduj () {
	$('#logo').css({'visibility' : 'hidden'});
	$('#content').hide();  
	var ilosczaladowanych = 0;
	var postep = 0;
	var obrazki = [];
	var y = 0;
	for(var x=0; x< nazwy.length; x++) {
		obrazki[x] = new Image();
		obrazki[x].src = nazwy[x];
		obrazki[x].onload = function() {
    	ilosczaladowanych += 1;
		postep = Math.round(ilosczaladowanych*100/nazwy.length)+"%";
		$('#procent').text(postep);
		if (postep == "100%") {
			koniecLadowania();
			}	
		}	
	}
}





$(document).ready(Laduj);
</script>

jeszcze jakies pomysly? bo jak nie to ja juz nie wiem gdzie szukac bledu, pisalem ten kod 3x od nowa.. poza tym rozpisywałem na 3 rozne funkcje, dodawałem arguments.callee; do funkcji anonimowej, w roznych miejscach umieszczalem licznik, rozne warunki, rozne wartosci, w roznych miejscach deklarowane zmienne, badanie przebiegu skryptu alertami i nic, zawsze jakis error.. w firefoxie działa zamieszczony powyzej kod. nic nie rozumie. chyba pozostaje mi jeszcze liczyc, ze @bswierczynski po zapoznaniu się ze skryptem cos wymysli echh

0

@DewREW:
Najlepiej by było jakbym po prostu ściągnął całą paczkę z Twoim kodem, obrazkami itd. Próbowałem chyba z 5x ściągnąć z tego sendspace'a, ale dostaję tylko komunikat: "Serwer z którego próbujesz pobrać plik jest chwilowo niedostępny."

Jeśli wygrzebiesz z forum mojego maila i ta paczka zajmuje < 20 MB to wyślij mi ją. Może znajdę czas by zerknąć. Schemat kodu, który zamieścił @kubARek, wydaje mi się dobry i logiczny.

0
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
<head>
  <title>Loader Test</title>
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  <script>
  var Load = function() {
  
   // znalezione na images.google.com
    var obrazkiDoZaladowania = [
      'http://upload.wikimedia.org/wikipedia/commons/d/d1/009Krak%C3%B3wRynek.jpg',
      'http://www.babelkowo.com/wp-content/gallery/ale/GB%20%28115%29.JPG',
      'http://upload.wikimedia.org/wikipedia/commons/e/ea/Jaworzno-Deptak.JPG',
      'http://blog.lisewski.info/wp-content/uploads/2009/10/dscn2698.jpg',
      'http://nepomuki.pl/nepomuk/JN-GSlask-Jaworzno10_2008.jpg'
    ];
    var obrazkiZaladowane = 0;
    for (var i = 0; i < obrazkiDoZaladowania.length; i++) {
      var obrazek = new Image();

      // dodaj zdarzenie onload do tego obrazka
      obrazek.onload = function() {
        obrazkiZaladowane += 1;
        
        document.getElementById("progress").innerHTML = (obrazkiZaladowane * 100 / obrazkiDoZaladowania.length) + '%';
       
       // jeśli licznik pokazuje, że zostały załadowane wszystkie zdjęcia
        if (obrazkiZaladowane == obrazkiDoZaladowania.length)
          koniecLadowania();
      }
      // przypisz link, w tym momencie obrazek zacznie się ładować, jak skończy, zostanie wywołana funkcja onload
      obrazek.src = obrazkiDoZaladowania[i];
    }

    var koniecLadowania = function() {
      document.getElementById("loader").style.display = "none";
      document.getElementById("content").style.display = "block";
    };
  
  };
  
  onload = Load;
  
  </script>
</head>
<body>
    <div id="loader">
      Postęp: <span id="progress">0%</span>
    </div>
    
    <div id="content" style="display: none;">
      <h1>OK!</h1>
    </div>

Coś takiego wyskrobałem, no i chodzi pięknie pod IE, także pod Firefoxem. Pod Operą faktycznie nie działało, ale ustawiłem DOCTYPE odpowiednie ( żeby przeglądarka nie korzystała z trybu kompatybliności wstecznej ) i poszło. Może tu tkwi problem?

W ogóle to ten kod wyżej przepisz do jQuery, dodaj swoje ficzery i powinno już naprawdę działać :)

0

przepisałem ten kod który podałeś. i wyglada on do zludzenia tak samo jak wiekszosc poprzednich ktore pisalem.. ale.. w Operze i tak mi sie wysypal :| odinstalowalem opere.. w srode zaktualizowalem do jakiejs wyzszej,a wiec teraz powrocilem do poprzedniej jaka posiadalem czyli opery 10.10.. i jaki efeket? skrypt sie wykonal do konca [???] nie wiem jak to mozliwe.. ale teraz dziala.. takze dzieki..

teraz jeszcze tylko..
$("#pasek").hide("clip", {}, 1000);
ten kod nie ukrywa mi w ogole diva. moze to byc zalezne od tego ze tlem diva jest .gif? firefox wywala taki blad

Błąd: c.easing[this.options.specialEasing && this.options.specialEasing[this.prop] || a] is not a function
Plik źródłowy: file:///E:/jquery.js
Wiersz: 143

i..
czemu przy takim zapisie

function pomin() {
	alert('aaa');
}

$('#div').click(pomin());

alert pojawia sie Od razu po zaladowaniu strony, a nie przy kliknieciu na "#div"? chce po prostu z poziomu js nadac divowi zdarzenie onclick.. co znowu zle pisze? ;]

PS. @bswierczynski, wyslalem Ci ten plik na poczte, mimo wszystko jezeli znajdziesz chwile to zajrzyj do niego, w tamtym skrypcie moga byc jakies bledy i w razie czegos chcialbym wiedziec jakie : )

0

Zauważ, że jakbyś zrobił tak:pomin() to funkcja wykona się od razu. Niczym więc nie różni się od tego: $("#div").click(pomin())</code>. Rozwiązanie jest proste: <code class="javascript">$("#div").click(pomin);

firefox wywala taki blad
Co do tego błędu, to poszukaj na google, ja nie używam raczej jQuery UI, nie lubię jak komputer zamula ;)

0

@DewREW:
Co do tego błędu w jQuery, to po prostu próbujesz tam użyć niestandardowej metody animacji ("easingu", z angielskiego), niedostępnej od razu w jQuery. Powinna pomóc zamiana tego:

$("#pasek").hide("clip", {}, 1000);

Na po prostu to:

$("#pasek").hide(1000);

Jeśli chcesz użyć jakiejś funkcji z jQuery, to poczytaj o niej na api.jquery.com. Tam są opisane wszystkie standardowe opcje. Np. funkcja hide wcale nie ma (oficjalnie) trzech parametrów -- tak jak masz w kodzie -- tylko dwa, z czego drugi jest opcjonalny.

A ten problem z pomin... Cóż, najlepiej to chyba wytłumaczyć na przykładzie.

function moja_funkcja() {
  return 4;
}

var referencja_do_mojej_funkcji = moja_funkcja;   // (1)
var wynik                       = moja_funkcja(); // (2)

Funkcji click() powinieneś podać referencję do funkcji, która ma zostać wykonana po kliknięciu. Gdy używamy referencji do funkcji, to piszemy tylko jej nazwę, ale bez nawiasów okrągłych -- nie wywołujemy jej, tylko ją przypisujemy! W powyższym przykładzie referencję do funkcji przypisujemy do zmiennej referencja_do_mojej_funkcji w linii oznaczonej przez (1).

Z kolei do drugiej zmiennej -- o nazwie wynik -- przypisujemy nie referencję do funkcji, tylko wynik jej działania. Więc używamy nawiasów okrągłych za nazwą funkcji. moja_funkcja jest odpalana, a zwrócona przez nią wartość, czyli 4, zostaje podstawiona do zmiennej wynik. Zmienna wynik ma więc wartość 4.

0

hm.. musze przyznac, że sporo mi pomogliscie :) na innym forum napisałem ponad tydzień temu i nie dostałem do dzisiaj zadnej odpowiedzi ^^
@kubARek - dlaczego odradzasz korzystanie z jQueryUI? przyjrzałem się tej wtyczce i muszę przyznać, że parę efektów wydaję się być interesujących i chętnie skorzystałbym z nich.

jeszcze opiszę taka sytuacje.. wykonuje się jakaś funkcja po wczytaniu drzewa DOM. i ona sobie trwa, przykładowo coś tam animuje. teraz przy kliknieciu w jakis odnosnik chcę żeby wywolana została inna funkcja która przerwie tą która już działa. jest to mozliwe? jak?

może od razu już napiszę coś co sprawi mi również za niedługo problem, a mianowicie:
chciałbym stworzyć dynamiczną galerie, której pierwsza strona wyświetli się po kliknięciu w odpowiedni odnosnik. galerie wyglądająca mniej wiecej tak:

X X X

X X X

X X X

piszac "dynamiczna" mam na myśli to, żeby program sam tworzył miniaturki zdjęć, znalazł im odpowiednie miejsce i ustawił zgodne z powyższym schematem dla wszystkich obrazków do których zamieszczę odnośniki w jakieś tablicy.. a gdy przypuśćmy 9 zdjęć już znajdzie się w divie, chciałbym żeby stworzył kolejny i wypełniał go zgodnie z poprzednim... zastanawiam sie pomału jak to ugryźć..

1 użytkowników online, w tym zalogowanych: 0, gości: 1