"Rób, co możesz, w miejscu, jakim jesteś i z tym, co masz."

miniSlider – asynchroniczne ładowanie zdjęć

Krótko na temat miniSlider’a

Na potrzeby jednego z projektów potrzebowałem lekkiego i szybkiego slidera bez zbędnych dodatków czy efektów. Slider wykorzystuje bibliotekę jQuery upiększony został frameworkiem do css Bootstrap, który nie jest wymagany do działania. MiniSlider ładuje każde zdjęcie asynchronicznie, przy wywołaniu danego obrazka. Pozwala to na szybsze załadowanie strony, nawet gdy nasza aplikacja będzie musiała załadować 1000 zdjęć, odbędzie się to przy wywołaniu obrazka, a więc zmniejszy się zużycie transferu.

Dodatkowo slider wyświetla nam adres URL oraz pomocniczy tekst. Inicjalizacja slidera jest bardzo łatwa, jedyne czego potrzebujemy to json’a z tablicą obrazów.

 

Wyjaśnienie działania slidera w JQ – krótki tutorial

 

Zacznijmy od kilku klas CSS

.img-content {
     position: relative;
     min-width: 100%;
     min-height: 180px;
 }
.img-content img {
     min-width: 100%;
 }
.img-content .img-text {
     position: absolute;
     width: 100%;
     bottom: 0px;
     background: rgba(0,0,0,0.5);
     text-align: center;
     color: #FEFEFE;
     padding-top: 4px;
     padding-bottom: 4px;
 }

Klasa .img-content jest boxem na obrazek oraz tekst pomocniczy. Ustawione minimalne wymiary oraz pozycjonowanie relatywne, które pozwala tekstowi pomocniczemu wypozycjonować się na dole obrazka.
Klasa .img-text jest kontenerem na tekst pomocniczy. Atrybut position: absolute pozwala na wypozycjonowanie się względem boxa .img-content natomiast bottom: 0px pozycjonuje tekst na dole obrazka, a width: 100% rozciąga go na całą szerokość.

 

Teraz troszkę więcej kodu – jQuery

Na samym początku muszę Wam napisać że cały kod slidera opakowany jest w funkcję samowywołującą się.

var imageSwitch = (function (){
    // Ciało funkcji i zmienne, które napiszemy
    
    return {
        init: init
    }
})();

Taka funkcja pozwala nam na odseparowanie zmiennych i ograniczenie naszego kodu, przez co będziemy pewni że inny kod nie nadpisze nam naszej zmiennej czy dodatkowych funkcji. Na temat takiej funkcji zrobię osobny artykuł z dokładniejszym wytłumaczeniem.

Lećmy dalej 😉 Następnie użyłem krótkiego powiadomienia przeglądarki i interpretatora JavaScript za pomocą "use strict"; że będziemy używać 'trybu ścisłego’ czyli nasz kod będzie sprawdzany w lepszy sposób, co pozwoli nam na zachowanie wyższej jakości kodu.

Utworzymy sobie 3 zmienne, które będą przetrzymywać nam analogicznie: tablicę obrazów, ilość zdjęć oraz index aktualnie wybranego zdjęcia.

 var images = [];
 var countImg = 0;
 var indexImg = 1;

 

Funkcja ładująca zdjęcie asynchronicznie

Teraz przejdziemy sobie do utworzenia pierwszej funkcji loadImage(__index) za pomocą której będziemy ładowali asynchronicznie obrazek do dokumentu HTML. Funkcji przekazujemy __index (zaczyna się od 1) do wyświetlenia poprawnego obrazka.

function loadImage(__index){
    images.forEach(function(img, index){
        if(index == __index - 1){
            // Ładowanie zdjęcia oraz atrybutu alt
            $('.img-content > img').attr('src', img.src).attr('alt', img.alt);

               // Ustawia opis zdjęcia
               $('.img-content > .img-text').text(img.text);
               // W polu input wyświetla link do zdjęcia
               $('.img-input-src').val(img.src);
            }
     });
 }

Zmienną images potraktujemy sobie pętlą forEach() , której w pierw musimy przekazać anonimową funkcję z parametrami (img, index), gdzie img przechowuje wybrany obrazek a index numer (zaczyna się od 0, tak jak każdy element w tablicy) wskazywanego elementu. Następnie sprawdzamy czy index tablicy obrazków jest równy wybranemu elementowi z tablicy __index (pamiętaj że musisz odjąć jedynkę, ponieważ elementy w tablicy rozpoczynają się od 0 a nasze zliczanie elementów od 1).

Gdy wybrany obrazek nam się zgadza za pomocą specjalnej funkcji w jQuery $(elementHTML) łapiemy nasz obrazek $('.img-content > img') i ustawiamy atrybut src attr('src', img.src) oraz atrybut alt (nie wymagane) attr('alt', img.alt) .

Potem ustawiamy tekst pomocniczy obrazka $('.img-content > .img-text').text(img.text); oraz adres url w polu input-text $('.img-input-src').val(img.src); .

 

Krótka funkcja zmieniająca statusy

Utworzymy sobie mała funkcję, która będzie wykonywać akcje na elementach HTML.

function changeStatus(){
    $('.img-control .img-index').text(indexImg);
    $('.img-control .img-count').text(countImg);
    $('.img-content > img').attr('src', 'images/loader.gif');
    $('.img-content > .img-text').empty();
    $('.img-input-src').val('');
 }

Dwie pierwsze linijki wewnątrz funkcji ustawiają na widoku index (klasa .img-index) i ilość obrazów (klasa .img-count).

Trzecia z kolei linijka ładuje GIFa imitującego ładowanie zdjęcia.

Czwarta i piąta czyszczą pole tekstu pomocniczego oraz wyświetlany adres url obrazka.

 

Funkcje zmieniające obrazek

Do zmiennej actions przypisujemy dwie funkcje previous oraz next – pierwsza cofa zdjęcia a druga wybiera następne.

var actions = {
    previous : function(){
        if(indexImg > 1 && indexImg <= countImg){
           indexImg --;
        } else {
           indexImg = countImg;
        }
        changeStatus();
        loadImage(indexImg);
   }, // Koniec funkcji previous

    next : function(){
        if(countImg >= 1) {
            if (indexImg < countImg) {
                indexImg++;
            } else {
                indexImg = 1;
            }
        }
        changeStatus();
        loadImage(indexImg);
    } // Koniec funkcji next
 };

Na samym początku w oby dwóch funkcjach sprawdzamy aktualny index i nie pozwalamy mu wykroczyć po za zakres liczby obrazów, jeżeli dojdziemy do ostatniego elementu to indexImg wraca do stanu początkowego.
Po sprawdzeniu indexu wywołujemy funkcję changeStatus() oraz  funkcję ładującą loadImage(indexImg) z przekazanym numerem obrazu. W innym miejscu kodu te dwie funkcje podepniemy sobie pod przyciski.

 

Główna funkcja init()

Nadszedł czas by napisać naszą główną funkcję naszej mini biblioteki do obsługi naszego małego slidera. Funkcja będzie mieć za zadanie połączyć w całość wszystkie powyższe funkcje oraz pobrać listę obrazów. A więc o to jej kod:

function init(img){
    images = img;
    countImg = img.length;
    indexImg = (countImg > 0) ? 1 : countImg;

    changeStatus();
    loadImage(1);

    // Przypisanie funkcji wstecz oraz dalej dla akcji w JQ click
    $('.img-control .previous').click(actions.previous);
    $('.img-control .next').click(actions.next);
 }

Przekazywany w funkcji parametr img, przypisuje do zmiennej images tablicę obrazów, następnie do countImg pobieramy ilość elementów oraz ustawiamy pierwszy element, chyba że tablica jest pusta to do zmiennej indexImg wstawiamy 0. Potem dwie funkcje, które już znamy. Natomiast ładujemy od razu pierwszy obrazek – nie ma potrzeby sprawdzenia czy one istnieją, ponieważ istniejąca tam pętla forEach nie wywoła się.

 

Teraz troszkę kodu HTML

Go chyba nie trzeba opisywać 😉

<ul class="img-control pager">
   <li class="previous"><a href="#">&larr; Wstecz</a></li>
   <li class="next"><a href="#">Dalej &rarr;</a></li>
   <li><span class="img-index">0</span> <b>/</b> <span class="img-count">0</span></li>
</ul>
<div class="img-content ">
   <img src="images/loader.gif" class="img-responsive" />
   <div class="img-text"></div>
</div>

<label for="imgsrc">Link do zdjęcia:</label>
<input id="imgsrc" class="img-input-src form-control" type="text" readonly />

 

Wywołanie naszego slidera !

To już prawie koniec pisania naszego kodu, jedyne co nam pozostało to wywołanie naszej biblioteki slidera w funkcji jQuery oraz przekazania jej obrazków.

$(function(){
   var x = [
    {
      src: "images/zdj-1.jpeg",
      alt: "Alt zdjęcia 1",
      text: "Zdjęcie z dysku 1"
    },
    {
     src: "images/zdj-2.jpeg",
     alt: "Alt zdjęcia 2",
     text: "Zdjęcie z dysku 2"
    }
  ];

   imageSwitch.init(x);
 });

 

 

Polecam zerknąć do gotowego kodu jak to wszystko wygląda, znajduje on się na moim GitHubie pod tym linkiem, całość znajdziesz w pliku index.html .

Udostępniłem również demo, które możesz przetestować tutaj.

 

Jeżeli uznasz że ten artykuł jest ciekawy, podziel się nim. A w razie jakichkolwiek pytań pisz (kontakt).

Pozdrawiam 😉

Share This: