Lazy load images
module LazyLoader { | |
const attributeName = "data-src"; | |
function throttle(wait: number, func: () => any, immediate = false) { | |
var context: any; | |
var args: any; | |
var timeoutHandle: number; | |
var result: any; | |
var previous: Date; | |
var later = () => { | |
previous = new Date(); | |
timeoutHandle = null; | |
result = func.apply(context, args); | |
}; | |
return function () { | |
const now: Date = new Date(); | |
if (!previous && immediate === false) previous = now; | |
var remaining = wait - (<any>now - <any>previous); | |
context = this; | |
args = arguments; | |
if (remaining <= 0) { | |
clearTimeout(timeoutHandle); | |
timeoutHandle = null; | |
previous = now; | |
result = func.apply(context, args); | |
} else if (!timeoutHandle) { | |
timeoutHandle = setTimeout(later, remaining); | |
} | |
return result; | |
}; | |
} | |
function isElementInViewport(element: Element) { | |
const rect = element.getBoundingClientRect(); | |
return (rect.top >= 0 && | |
rect.left >= 0 && | |
rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) && | |
rect.right <= (window.innerWidth || document.documentElement.clientWidth) | |
); | |
} | |
function loadImagesInViewport() { | |
// Peut être amélioré en cas de besoin en cherchant uniquement les images visibles | |
// Par exemple une image dans une modal ou un onglet | |
// TODO picture, srcset | |
const imgs = document.querySelectorAll(`img[${attributeName}]`); | |
for (let i = 0; i < imgs.length; i++) { | |
const img = imgs[i] as HTMLImageElement; | |
if (isElementInViewport(img)) { | |
console.log("Loading image", img); | |
img.src = img.getAttribute(attributeName); | |
img.removeAttribute(attributeName); | |
} | |
} | |
if (imgs.length === 0) { | |
console.log("Remove lazy loading event handlers"); | |
unregisterEvents(); | |
} | |
} | |
var eventHandler = throttle(100, () => { | |
console.log("Check img[data-src]"); | |
loadImagesInViewport(); | |
}); | |
function registerEvents() { | |
document.addEventListener("DOMContentLoaded", eventHandler); | |
document.addEventListener("load", eventHandler); | |
document.addEventListener("scroll", eventHandler); | |
document.addEventListener("resize", eventHandler); | |
} | |
function unregisterEvents() { | |
document.removeEventListener("DOMContentLoaded", eventHandler); | |
document.removeEventListener("load", eventHandler); | |
document.removeEventListener("scroll", eventHandler); | |
document.removeEventListener("resize", eventHandler); | |
} | |
registerEvents(); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment