chevron-left chevron-right

[jQuery] Zmiana widoku listy za pomocą jQuery

Dzisiejszy wpis będzie krótki, lecz treściwy. Jego celem będzie przedstawienie sposobu na dynamiczną zmianę wyglądu listy za pomocą kilku kawałków kodu JS/jQuery.

Struktura kodu HTML

Na początek musimy przygotować strukturę kodu HTML. W tym przypadku wygląda ono następująco:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
<section id="filter" class="span12">
	<ul>
		<li class="span1">
			<span class="btn btn-warning" id="filter-list"><i class="icon-th-list"></i></span>
		</li>
		<li class="span1">
			<span class="btn btn-danger" id="filter-thumb"><i class="icon-th"></i></span>
		</li>
	</ul>
</section>
<section class="span12" id="items">
	<ul class="normal-list">
		<li >
			<figure>
				<img src="img/img.jpg" alt=""/>
				<figcaption>
					<h3>Tekst</h3>
					<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit.</p>
				</figcaption>
			</figure>
		</li>
		<li >
			<figure>
				<img src="img/img.jpg" alt=""/>
				<figcaption>
					<h3>Tekst</h3>
					<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit.</p>
				</figcaption>
			</figure>
		</li>
		<li >
			<figure>
				<img src="img/img.jpg" alt=""/>
				<figcaption>
					<h3>Tekst</h3>
					<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit.</p>
				</figcaption>
			</figure>
		</li>
		....
	</ul>
</section>

Najpierw zdefiniowałem sekcję w której będą przyciski do zmiany widoku. Element o id filter-list będzie odpowiedzialny za włączanie widoku listy, a element o id filter-thumb będzie odpowiedzialny za włączenie widoku miniaturek. W kolejnej sekcji znajduje się lista elementów, które zawierają obrazki oraz tekst pod nimi. W normalnym widoku tekst się pojawia obok obrazków. Natomiast w widoku miniaturek tekst do obrazka będzie się pojawiał jako dymek obok podczas najazdu myszki na obrazek.

Podstawowe style dla listy

W tym przykładzie postanowiłem wykorzystać kilka klas z frameworka Twitter Bootstrap uzupełnionych moim kodem CSS. Dodatkowy kod CSS wygląda następująco:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
ul 				{ list-style: none; }
figure				{ margin: 1.875%; }
h1				{ text-align: center; }
#page				{ margin: auto; }
#filter	ul			{ float: right; }
.normal-list li 		{
	clear: both;
	padding: 0.9375%;
	width: 100%;
}
.normal-list img 		{ 
	float: left;
	width: 10%;
	margin: 0.9375% 0.9375% 0 0;
}
.normal-list figcaption { 
	float: left;
	width: 89%;
}
.thumb-list li {
	width: 22%;
	margin-right: 0.9375%;
	float: left;
	position: relative;
	display: inline-block;
	cursor: pointer;
}
.thumb-list li h3 	{ text-align: center; }
.thumb-list li p 	{
	/* ukrywamy paragraf z tekstem w widoku miniaturek */
	display: none;
	visibility: hidden;
}
.thumb-list li:hover p {
	/* tutaj wyświetlamy paragraf po najechaniu kursora myszki na element listy */
	display: block;
	visibility: visible;
	position: absolute;
	-webkit-border-radius: 4px;
	border-radius: 4px;
	background: #cfcfcf;
	width: 100%;
	right: -110%;
	top: 5px;
	z-index: 3;
	padding: 4%;
	-webkit-box-shadow: 0px 0px 4px 0px #333;
	box-shadow: 0px 0px 4px 0px #333;
}

Jak widać, kod nie jest specjalnie skomplikowany. Wykrozystałem upiększacze ze zbioru CSS3 takie jak: box-shadow i border-radius oraz dla dymka z tekstem ustawiłem pozycjonowanie absolutne aby dymek pojawiał się obok obrazka.

Interakcje z listą za pomocą kodu JS

W tym miejscu zostanie opisany kod JS odpowiedzialny za przełączanie widoku listy. Został on utworzony przy pomocy biblioteki jQuery, dlatego należy pamiętać, aby ją dołączyć do kodu. Sam kod odpowiedzialny za interkację użytkownika wygląda następująco:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
$(function () {
 
	function pde(e) {
	    if (e.preventDefault) {
	    	e.preventDefault();
	    } else {
	    	e.returnValue = false;
	    }
	}
 
	$('#filter-list').on('click', function (e) {
		pde(e);
		var items = $('ul','#items');
		if (!items.hasClass('normal-list')) {
			items.removeClass('thumb-list').addClass('normal-list');
		}
 
		var figure = items.find('figure');
		figure.each(function (k,v) {
			if ($(this).hasClass('thumbnail')) {
				$(this).removeClass('thumbnail');
			}
		});
	});
 
	$('#filter-thumb').on('click', function (e) {
		pde(e);
		var items = $('ul','#items');
		if (!items.hasClass('thumb-list')) {
			items.removeClass('normal-list').addClass('thumb-list');
		}
 
		$(items).find('figure').each(function (k) {
			$(this).addClass('thumbnail');
		});
	});
});

Powyższy kod obejmuje obsługę zdarzenia kliknięcia na każdym z przycisków. Po naciśnięciu przycsku następuje usunięcie i dodanie odpowiedniej klasy z/do elementów. W ten sposób można dynamicznie zmieniać wygląd listy.
Można zauważyć tez dodatkową rzecz jaką jest funkcja pde. Jest to funkcja odpowiedzialna za wykrywanie czy przeglądarka obsługuje blokowanie domyślnych zachowań elementów (bardzo przydatne w przypadku starszy wersji IE).

Podsumowanie

Powyższy kod przedstawia sposób na uzyskanie ciekawego efektu zmiany wyglądu listy za pomocą przełączników. Oprócz samej zmiany klas można kod uzupełnić o inne akcje, np. animacje przejścia między widokami. Tego typu rozwiązanie może być zastosowane w galeriach prac lub produktów, zwiększając przyjemność korzystania ze stron WWW.

Demo z tego artykułu jest dostępne tutaj: jQuery zmiana widoku listy

  • Albo za dużo piję albo pierwsza lista pogubiła cyferki jeżeli chodzi o numerowanie linii w kodzie.

  • Piotr Nalepa

    nie widzę tego problemu

  • Comandeer

    Sposób fajny, na pewno wykorzystam. ale 😉 AFAIR w jQuery eventy są normalizowane i e.preventDefault działa nawet w starszych IE. zatem funkcja pde jest zbędna. i taka jeszcze czepialska uwaga: czemu przyciski nie są przyciskami? 😀 ale to raczej zarzut do Bootstrapa i jego nie do końca semantycznego kodu…

  • Tak na moje oko to…

    var figure = items.find(‚figure’);
    figure.each(function (k,v) {
    if ($(this).hasClass(‚thumbnail’)) {
    $(this).removeClass(‚thumbnail’);
    }
    });

    …jest raczej zbędne, bo można złapać samą listę i dodać do niej style zależne w CSS – będzie minimalnie szybsza i mniej kodu w JS.

  • Piotr Nalepa

    Jasne, że tak. Masz rację. Lecz czasem chciałoby się uniknąć kopiowania stylów CSS dla niektórych elementów.