Dinamično nalaganje slik z jQuerijem

Zadnje čase sem na nekaterih straneh opazil, da se slike ne nalagajo kot je to v navadi ampak nekoliko neobičajno. Namesto slike se najprej prikaže kakšen preprosti gif, ki nakazuje, da se slika v ozadju nalaga. Takrat, ko se slika prenese v celoti, se gif zamenja z aktualno sliko. Na podoben način sedaj tudi google prikazuje slike, kjer ni treba več klikati na naslednjo stran, ampak se slike dodajajo na koncu seznama in dinamično naložijo.

Ker imam tudi sam kakšne projekte, kjer je zelo veliko slik prikazanih na strani (razne galerije ali trgovine), sem se odločil zadevo raziskati. Odkril sem, da je to relativno preprosto izvedljivo z nekaj vrsticami javascript kode, seveda z uporabo jQuery knjižnice. Poudariti moram tudi, da to ni dinamično nalaganje slik, v smislu, da slike eno za drugo nalagamo v celoti, ampak ima samo uporabnik vtis, kot da se to v ozadju dogaja.

Problem

Če imamo na strani veliko slik, lahko kar nekaj časa traja, da se stran v celoti prikaže. Lahko pride celo do preloma strukture strani, dokler se slike ne naložijo v celoti, če to s CSSjem ni predvideno. S tem vodičem se izognemo tem težavam. Še prijazneje pa je z vidika uporabnika, saj se slike, ko so prenesene na računalnik, v celoti prikažejo s fadeIn efektom.

Rešitev

Za izvedbo tega potrebujemo:

  • jQuery
  • Gif, ki prikazuje, da se nekaj dogaja
  • Sliko, ki se prikaže v primeru napake

HTML

HTML:
  1. <img src="" alt="images/example.jpg" />
  2. <img src="" alt="images/example1.jpg" />

Slika v HTMLju mora imeti class delayLoad, ker z pomočjo tega classa z jQuerijem dobimo slike, ki jih želimo dinamično naložiti. Atribut src je v začetku prazen, kasneje se v javascriptu nastavi na enako vrednost, kot jo ima atribut alt, kjer je shranjena dejanska pot do slike. Če vam ni všeč, da je src prazen, vam predlagam, da naredite transparentno sliko (1×1 px).

CSS

CSS:
  1. .delayLoad {
  2. background: url('images/ajax-loader.gif') no-repeat 50% 50%;
  3. }

Do sedaj bi moralo biti še vse jasno, saj je to standardna HTML in CSS koda. S CSSjem sem dodal gif za ozadje, ki ga uporabnik vidi namesto slike, dokler le-ta ni naložena.

Javascript koda

JAVASCRIPT:
  1. //Z ready funkcijo povemo, da se ta koda začne izvajati, ko je stran naložena
  2. jQuery(document).ready(function() {
  3. //poiščemo vse slike z classom delayLoad
  4. jQuery("img.delayLoad").each(function() {
  5.  
  6. // Ustvarimo span element, ki ga bomo s pomočjo jQuery funkcije wrap dodali okoli posamezne slike
  7. // Primer:
  8. // <span>
  9. // <img src='' alt='' />
  10. // </span>
  11. var delaySpan =  document.createElement("span");
  12.  
  13. //to samo pomeni, da mi znotraj tega ni potrebno pisati jQuery(this).css
  14. with (jQuery(this)) {
  15. //Za slike, ki so skrite in jih želimo dinamično naložiti ni potrebno, da je gif viden.
  16. //Drugače pa mora span imeti atribut display nastavljen na 'block', ker opcija 'inline' ne deluje dobro.
  17. if (css('display') == 'none') {
  18. var _display = 'none'
  19. }else {
  20. var _display = 'block'
  21. }
  22.  
  23. //kopiramo CSS od trenutne slike v span zato, da nam ga ni potrebno posebej oblikovati.
  24. var cssObj = {
  25. 'height' : css('height'),
  26. 'width' : css('width'),
  27. 'margin-top' : css('margin-top'),
  28. 'margin-right' : css('margin-right'),
  29. 'margin-bottom' : css('margin-bottom'),
  30. 'margin-left' : css('margin-left'),
  31. 'background-image' : css('background-image'),
  32. 'background-color' : css('background-color'),
  33. 'background-repeat' : css('background-repeat'),
  34. // Zaradi IE, ker ne zna pravilno prebrati lastnosti background-position (ostale CSS lasnosti se vzamejo iz trenutne slike)
  35. 'background-position' : '50% 50%',
  36. 'display' : _display
  37. }
  38. }
  39. // Spanu dodamo CSS, zato da bo izpis na strani enak pred in po naloženi sliki
  40. jQuery(delaySpan).css(cssObj);
  41.  
  42. // Span element dodamo okoli slike
  43. jQuery(this).wrap(delaySpan)
  44.  
  45. // Sliko skrijem, viden ostane samo span z gifom
  46. .hide()
  47.  
  48. //sliki spremenimo src, ki ga preberemo iz alt atributa
  49. .attr('src', this.alt)
  50.  
  51. // ta klic funkcije se izvede, ko je slika v celoti naložena
  52. .load(function () {
  53. //sliko prikažemo z fadeIn efektom in odstranimo dodani span.
  54. jQuery(this).fadeIn().unwrap();
  55. })
  56.  
  57. //v primeru, da slika ne obstaja ali če pride do kakšne napake, se izvede error funkcija namesto load,
  58. //v njej nastavim osnovno sliko in odstranim kreirani span element
  59. .error(function() {
  60. jQuery(this).attr('src', "images/error.jpg");
  61. jQuery(this).fadeIn().unwrap();
  62. });
  63. });
  64. });

Zaključek

Zadeva je lahko izvedljiva, če imate osnovno razumevanje javascripta. Ima omejitev, da uporabniki brez javascripta ne bodo videli slik. Vendar mislim, da to v današnjih časih ne bi smel biti problem. Saj imajo v osnovi vsi brskalniki vključen javascript. To sem testiral v Firefoxu in vseh relevantnih verzija IEja in super dela.

Imaš kakšen komentar ali popravke? Si kdaj delal kaj podobnega, kako si se ti lotil tega problema?

Viri in literatura

  • purplepixelmedia.co.uk za osnovo sem si vzel ta vodič in ga dodelal, da se slike nalagajo on load in dodana je funkcija error
  • blog.realmofzod.com Implementiral podobno funkcijo error kot je tu uporabljena.

Podobni članki:

  1. CSS3 gumb (brez Photoshop-a)
  2. CSS pseudo classes
  3. Responsive Web Design – 1.del
  4. {box-sizing: border-box}
  5. LESS CSS

Dodaj komentar