Wpisy otagowane ‘absolute’

Ruch na stronie z jQuery

wtorek, 15 Październik 2013

Nie będę pisał o tym, jak zwiększyć ruch na stronie w sensie ilości użytkowników odwiedzających serwis, tylko o wprowadzeniu ruchomych elementów reagujących na określone zachowania użytkownika. Skorzystam przy tym z dobrodziejstw JavaScriptu i biblioteki jQuery. Jeżeli nie znasz jQuery, przeczytaj Co mogę zrobić z jQuery?.

Efekt, którego realizację chcę tu przybliżyć, zaprezentowałem poniżej. Najedź myszą na kolejne grafiki. Dalej znajdziesz kolejne etapy jego realizacji.

Obraz 1.

Obraz 2.

Obraz 3.

Obraz 4.

Obraz 5.

Obraz 6.

Zaczniemy od kodu HTML:

<div id="photos">
<div class="photo">
 	<div class="text"><p>Obraz 1.</p></div>
 	<img src="img1.jpg" id="p1" />
</div>
<div class="photo">
 	<div class="text"><p>Obraz 2.</p></div>
 	<img src="img2.jpg" id="p2" />
</div>
<div class="photo">
 	<div class="text"><p>Obraz 3.</p></div>
 	<img src="img3.jpg" id="p3" />
</div>
<div class="photo">
 	<div class="text"><p>Obraz 4.</p></div>
 	<img src="img4.jpg" id="p4" />
</div>
<div class="photo">
 	<div class="text"><p>Obraz 5.</p></div>
 	<img src="img5.jpg" id="p5" />
</div>
<div class="photo">
 	<div class="text"><p>Obraz 6.</p></div>
 	<img src="img6.jpg" id="p6" />
</div>
</div>

Całość znajduje się w znacznikach div z identyfikatorem photos. W zależności od szerokości tego elementu w jednym wierszu znajdzie się większa lub mniejsza liczba grafik. Każda grafika składa się z dwóch części: górnej – widocznej od razu i dolnej – pokazującej się po najechaniu myszą. Do elementów img dodałem identyfikatory. Grafiki poprzedzone są opisami zawartymi w elementach div klasy text, a łącznie z grafiką w elementach div klasy photo. Te divy służą do ograniczenia widoczności grafik do połowy ich wysokości, co jest realizowane przez definicje styli CSS:

#photos
{
 	width: 750px;
 	margin: 20px auto;
}
.photo 
{
 	width: 350px;
 	height: 350px;
 	overflow: hidden;
 	display: inline-block;
 	position: relative;
}
img 
{
 	display: none;
 	position: relative;
 	top: 0px;
}
.text 
{
 	width: 100%;
 	height: 100px;
 	background: #fff;
 	position: absolute;
 	left: 0px;
 	bottom:-100px;
 	z-index: 100;
}

Div photos swoją szerokością ogranicza ilość grafik w wierszu. Klasa photo definiuje widoczny obszar dla każdego pliku graficznego do kwadratu o boku 350px. Właściwość overflow ustawiona na hidden ukrywa paski przewijania dla zawartości nie mieszczących się w zdefiniowanym obszarze, display: inline-block sprawia, że elementy tej klasy zachowują się na zewnątrz jak elementy liniowe (ustawiają się jeden za drugim), a wewnątrz są elementami blokowymi zachowującymi zdefiniowane wymiary. Pozycjonowanie relatywne pozwoli na użycie tych elementów jako odniesienia dla elementów zawartych wewnątrz nich. Elementy img początkowo nie są widoczne. Za ich pokazanie będzie odpowiedzialny odpowiedni kod jQuery. Pozycjonując te elementy będziemy mogli wpływać na ich wartość top liczoną względem zewnętrznego elementu pozycjonowanego relatywnie. Została nam jeszcze klasa text. Elementy tej klasy ze względu na to, że są mniejsze niż element nadrzędny są pozycjonowane absolutnie, czyli właściwość bottom odnosi się do dolnej krawędzi elementu nadrzędnego, a nie elementu klasy text. Ujemna wartość ukrywa tekst pod dolną krawędzią elementu klasy photo, a z-index z wartością 100 gwarantuje pojawianie się tekstu na, a nie pod grafiką.

Teraz ostatnia i najważniejsza część, czyli kod jQuery:

$(document).ready(function()
{
	$('#p1').fadeIn(1000);
 	$('#p2').delay(200).fadeIn(1000);
 	$('#p3').delay(400).fadeIn(1000);
 	$('#p4').delay(600).fadeIn(1000);
 	$('#p5').delay(800).fadeIn(1000);
 	$('#p6').delay(1000).fadeIn(1000);
 
 	$('.photo').mouseover(function()
 	{
 		if($('img',this).queue('fx').length==0)
		{
			$('img',this).animate({'top':'-350px'},500);
			$('div',this).delay(200).animate({'bottom':'0px'},800);
		}
 	});
 	$('.photo').mouseleave(function()
 	{
 		if($('img',this).queue('fx').length<2)
		{
			$('div',this).animate({'bottom':'-100px'},400);
			$('img',this).delay(200).animate({'top':'0px'},700);
		}
	});
});

Skrypt rozpoczynamy od pokazania kolejnych grafik z efektem fadeIn. Efekt dla każdego kolejnego obrazka odpala się z opóźnieniem 200 ms względem poprzedniego (funkcja delay() z argumentem o 200 wyższym od poprzedniego). Poniżej mamy obsługę dwóch zdarzeń: mouseover i mouseleave. W pierwszym przypadku mamy dwie animacje funkcją animate(). Najpierw przewijamy w górę grafikę, a potem tekst. Całość jest zawarta w instrukcji warunkowej, którą na razie pominę. Warto sprawdzić zachowanie skryptu bez instrukcji if przy jednym i drugim zdarzeniu. W mouseleave najpierw tekst wraca na miejsce początkowe (tuż pod dolną krawędź widocznego obszaru), a następnie grafika zjeżdża w dół.

Ponieważ w jQuery efekty animacji są kolejkowane, to wszystkie zdarzenia powodujące wywołanie animacji, będą dokładały te animacje do kolejki. Szybkie, kilkukrotne najechanie i opuszczenie kursorem myszy tej samej grafiki spowoduje utworzenie kolejki wielu efektów, które będą musiały być wykonane. Użytkownik nie będzie już nic robił, a obrazki będą się przesuwały w górę i w dół tyle razy, ile razy te efekty zostały wcześniej dodane do kolejki. Rozwiązaniem tego problemu jest kontrolowanie ilości efektów w kolejce, co umożliwia nam właściwość length obiektu queue. Właśnie tę funkcję realizują instrukcje warunkowe w obsłudze zdarzeń. W pierwszym przypadku nowe animacje będą dodane tylko w sytuacji gdy kolejka jest pusta. W drugim bierzemy pod uwagę fakt, że pierwsza faza może nie zostać zakończona, więc jeden efekt może jeszcze być obecny w kolejce.

Zaprezentowany w tym artykule przykład nie będzie działał poprawnie w przeglądarkach IE8 i wcześniejszych ze względu na użytą wartość display: inline-block, której wymienione przeglądarki nie obsługują. Jeżeli komuś zależy na tych przeglądarkach powinien wymienić display: inline-block na float: left. Możliwe, że będzie to wymagało dopracowania kilku innych szczegółów.



Ustalanie pozycji elementów w CSS cz. 2.

wtorek, 11 Styczeń 2011

Pozycjonowanie absolutne

W pozycjonowaniu absolutnym określamy pozycje elementu względem kontenera. Kontenerem zazwyczaj jest element body, może też być nim inny element z właściwością position ustawioną na relative, absolute lub fixed. Elementy występujące po elemencie pozycjonowanym zajmują miejsce tego elementu. Pozycje tradycyjnie ustala się właściwościami left, right, top i bottom. W przypadku gdy ustalamy właściwość top, a kontenerem jest element body, pozycja jest liczona od dolnej krawędzi części widocznej po załadowaniu strony. Samo pozycjonowanie absolutne jest określane właściwością position: absolute;. Poniżej przedstawiłem element pozycjonowany absolutnie w czerwonym obramowaniu. Dla większej jasności po elemencie pozycjonowanym umieściłem element dodatkowy (zielone tło), a całość umieszczam w elemencie z szaro-niebieską ramką.

<div class="ramka">
	<div class="border" id="absolute1">Element w pierwotnym położeniu</div>
	<div class="dodatkowy">Element dodatkowy</div>
</div>
#absolute1
{
	position: absolute;
}
.border
{
	margin: 15px;
	border: 2px solid #b80400;
	padding: 10px;
	background-color: #ffffff;
}
.ramka
{
	width: 350px; 
	border: 1px solid #9999cc;
}
.dodatkowy
{
	margin: 8px;
	padding: 12px;
	background-color: #33ff99;
	color: #ffffff;
	font-weight: bold;
}
Element w pierwotnym położeniu
Element dodatkowy


<div class="ramka">
	<div class="border" id="absolute2">
	Element z właściwością left: 40px; - odsunięty od lewej krawędzi kontenera o 40 pikseli
	</div>
	<div class="dodatkowy">Element dodatkowy</div>
</div>
#absolute2
{
	position: absolute;
	left: 40px;
}
.border
{
	margin: 15px;
	border: 2px solid #b80400;
	padding: 10px;
	background-color: #ffffff;
}
.ramka
{
	width: 350px; 
	border: 1px solid #9999cc;
}
.dodatkowy
{
	margin: 8px;
	padding: 12px;
	background-color: #33ff99;
	color: #ffffff;
	font-weight: bold;
}
Element z właściwością left: 40px; – odsunięty od lewej krawędzi kontenera o 40 pikseli
Element dodatkowy


<div class="ramka">
	<div class="border" id="absolute3">
	Element z właściwością right: 40px; - odsunięty od prawej krawędzi kontenera o 40 pikseli
	</div>
	<div class="dodatkowy">Element dodatkowy</div>
</div>
#absolute3
{
	position: absolute;
	right: 40px;
}
.border
{
	margin: 15px;
	border: 2px solid #b80400;
	padding: 10px;
	background-color: #ffffff;
}
.ramka
{
	width: 350px; 
	border: 1px solid #9999cc;
}
.dodatkowy
{
	margin: 8px;
	padding: 12px;
	background-color: #33ff99;
	color: #ffffff;
	font-weight: bold;
}
Element z właściwością right: 40px; – odsunięty od prawej krawędzi kontenera o 40 pikseli
Element dodatkowy


<div class="ramka">
	<div class="border" id="absolute4">
	Element z właściwością bottom: 10px; - odsunięty od dolnej krawędzi kontenera o 10 pikseli
	</div>
	<div class="dodatkowy">Element dodatkowy</div>
</div>
#absolute4
{
	position: absolute;
	bottom: 10px;
}
.border
{
	margin: 15px;
	border: 2px solid #b80400;
	padding: 10px;
	background-color: #ffffff;
}
.ramka
{
	width: 350px; 
	border: 1px solid #9999cc;
}
.dodatkowy
{
	margin: 8px;
	padding: 12px;
	background-color: #33ff99;
	color: #ffffff;
	font-weight: bold;
}
Element z właściwością bottom: 10px; – odsunięty od dolnej krawędzi kontenera o 10 pikseli
Element dodatkowy


<div class="ramka">
	<div class="border" id="absolute5">
	Element z właściwością top: 3500px; - odsunięty od górnej krawędzi kontenera o 3500 pikseli
	</div>
	<div class="dodatkowy">Element dodatkowy</div>
</div>
#absolute5
{
	position: absolute;
	top: 3500px;
}
.border
{
	margin: 15px;
	border: 2px solid #b80400;
	padding: 10px;
	background-color: #ffffff;
}
.ramka
{
	width: 350px; 
	border: 1px solid #9999cc;
}
.dodatkowy
{
	margin: 8px;
	padding: 12px;
	background-color: #33ff99;
	color: #ffffff;
	font-weight: bold;
}
Element z właściwością top: 3500px; – odsunięty od górnej krawędzi kontenera o 3500 pikseli
Element dodatkowy


<div class="ramka">
	<div class="border" id="absolute6">
	Element z właściwościami left: 40px; i top: 4500px - odsunięty od lewej krawędzi kontenera o 40 pikseli oraz od górnej krawędzi o 4500 pikseli
	</div>
	<div class="dodatkowy">Element dodatkowy</div>
</div>
#absolute6
{
	position: absolute;
	left: 40px;
	top: 4500px;
}
.border
{
	margin: 15px;
	border: 2px solid #b80400;
	padding: 10px;
	background-color: #ffffff;
}
.ramka
{
	width: 350px; 
	border: 1px solid #9999cc;
}
.dodatkowy
{
	margin: 8px;
	padding: 12px;
	background-color: #33ff99;
	color: #ffffff;
	font-weight: bold;
}
Element z właściwościami left: 40px; i top: 4500px – odsunięty od lewej krawędzi kontenera o 40 pikseli oraz od górnej krawędzi o 4500 pikseli
Element dodatkowy


<div class="ramka" id="relative">
	<div class="border" id="absolute7">
	Element z właściwościami left: 40px; i top: 50px - odsunięty od lewej krawędzi kontenera o 40 pikseli oraz od górnej krawędzi o 50 pikseli. W tym przypadku kontenerem jest element o identyfikatorze relative.
	</div>
	<div class="dodatkowy">Element dodatkowy</div>
</div>
#absolute6
{
	position: absolute;
	left: 40px;
	top: 50px;
}
#relative
{
	position: relative;
	left: -30px;
	top: 10px;
}
.border
{
	margin: 15px;
	border: 2px solid #b80400;
	padding: 10px;
	background-color: #ffffff;
}
.ramka
{
	width: 350px; 
	border: 1px solid #9999cc;
}
.dodatkowy
{
	margin: 8px;
	padding: 12px;
	background-color: #33ff99;
	color: #ffffff;
	font-weight: bold;
}
Element z właściwościami left: 40px; i top: 50px – odsunięty od lewej krawędzi kontenera o 40 pikseli oraz od górnej krawędzi o 50 pikseli. W tym przypadku kontenerem jest element o identyfikatorze relative.
Element dodatkowy

Zachęcam do pozostawieni swoich uwag i komentarzy poniżej.