Lazyload es un termino muy utilizado para las pre-carga de imágenes para un sitio web, mas que todo utilizado para la optimización de los mismos.
Mis objetivos son los siguientes:
- Tratar de hacer un código que no pese mas de 2kb
- Usar una imagen placeholder (es la primera imagen que se muestra)
- Dar 2 efectos al mostrar la imagen: Opacity, Blur
Pasos:
Comenzamos con iniciar nuestro codigo HTML:
1 2 3 4 5 6 7 8 9 10 11 | <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1"> <title></title> </head> <body> </body> </html> |
En el cual comenzaremos agregando nuestro CSS inicial:
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 | figure, a { border: 0; margin: 0; padding: 0; display: inline-block; } figure img { width: 100%; } .lazy-images-placeholder { background: url("https://revistaimage.com/wp-content/uploads/2016/08/placeholder-3-1.jpg"); background-position: center; background-repeat: no-repeat; background-size: cover; display: block; overflow: hidden; } .lazy-images-placeholder img { display: block; visibility: hidden; opacity: 0; filter: blur(20px); transition: opacity 1s ease-in-out, filter 1s ease-in-out; } .lazy-images-placeholder img.lazy-images-loaded { visibility: visible; filter: blur(0); opacity: 1; } |
En nuestro código CSS, lo que hice fue:
- Reiniciolos valores de los tags que voy a utilizar(en este caso son «figure» y «a»)
- A las imagenes que estarán dentro del tag «figure» les dare un ancho (width) de 100%
- He creado una clase llamada «lazy-images-placeholder» en cual sera nuestro tag «picture» que a la vez contendra nuestra imagen (tag «img») y sera nuestra imagen placeholder (imagen inicial)**
- En el tag «img» dentro de «lazy-images-placeholder» comenzare agregando opacity 0, visibility hidden, filter blur 20px, display blog
- En el mismo tag «img» agregare «transition: opacity 1s ease-in-out, filter 1s ease-in-out;», asignando transicion a los 2 propiedades que voy a utilizar «opacity» y «filter».
- He creado la clase llamada «.lazy-images-loaded» que se agregara al tag «img» una vez la imagen haya sido cargada con exito.
El formato de las imagenes que utilizare para comenzar con el JavaScript:
1 2 3 4 5 6 | <figure> <picture class="lazy-images-placeholder"> <img src="https://static.vix.com/es/sites/default/files/styles/large/public/t/thor-ragnarok-gladiator-hulk.jpg" class="lazy-images"> </picture> </figure> |
Comenzando con el código Javascript:
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 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 | (function () { // Asignamos en 2 variables AddEventListener y RemoveEventListener para asi no tener que llamarlos con window const addEventListener = window.addEventListener || function (n, f) { window.attachEvent('on' + n, f); }; const removeEventListener = window.removeEventListener || function (n, f, b) { window.detachEvent('on' + n, f); }; // Iniciamos nuestro LazyLoad const lazyLoad = { cache: [], // en esta variable almacenaremos todas las imagenes que encontremos en nuestro dom con la clase ".lazy-images" Timer: new Date().getTime(), // variable para setear la fecha actual (la necesitaremos para validar el momento que se agrego a la variable cache) addObservers: () => { // Un observador de funciones dentro de addEventLister y removeEventListener // Lo ponemos a escuchar "scroll" y "resize" para que ejecute la funcion lazyLoad.Load addEventListener('scroll', lazyLoad.Load); addEventListener('resize', lazyLoad.Load); }, Load: () => { let now = new Date().getTime(); if ((now - lazyLoad.Timer) >= 200) { lazyLoad.Timer = now; lazyLoad.loadVisibleImages(); } }, loadVisibleImages: () => { let scrollY = window.pageYOffset || document.documentElement.scrollTop; let pageHeight = window.innerHeight || document.documentElement.clientHeight; let range = { min: scrollY - 100, max: scrollY + pageHeight + 100 }; let i = 0; while (i < lazyLoad.cache.length) { let image = lazyLoad.cache[i]; let imagePosition = getOffsetTop(image); let imageHeight = image.height || 0; if ((imagePosition >= range.min - imageHeight) && (imagePosition <= range.max)) { let imgLoad = new Image(); imgLoad.src = image.src; imgLoad.onload = () => { image.classList.add('lazy-images-loaded'); }; lazyLoad.cache.splice(i, 1); continue; } i++; } if (lazyLoad.cache.length === 0) { lazyLoad.removeObservers(); } }, removeObservers: () => { removeEventListener('scroll', lazyLoad.Load, false); removeEventListener('resize', lazyLoad.Load, false); }, init: () => { if (!document.querySelectorAll) { document.querySelectorAll = function (selector) { const doc = document, head = doc.documentElement.firstChild, styleTag = doc.createElement('STYLE'); head.appendChild(styleTag); doc.__qsaels = []; styleTag.styleSheet.cssText = selector + "{x:expression(document.__qsaels.push(this))}"; window.scrollBy(0, 0); return doc.__qsaels; } } addEventListener('load', _init = () => { let imageNodes = document.querySelectorAll('.lazy-images'); for (let i = 0; i < imageNodes.length; i++) { let imageNode = imageNodes[i]; lazyLoad.cache.push(imageNode); } lazyLoad.addObservers(); lazyLoad.loadVisibleImages(); removeEventListener('load', _init, false); }); } }; const getOffsetTop = (el) => { let val = 0; if (el.offsetParent) { do { val += el.offsetTop; } while (el = el.offsetParent); return val; } }; lazyLoad.init(); })(); |
(Visited 172 times, 1 visits today)