I am using lazy load function for images in a section of my web page. (Basically the images currently shown in the viewport are fetched. Rest are not fetched from the server.) The following JavaScript works.
Usage Example: img class="lazy" src="/images/pixel.gif" data-src="/images/actual-image.jpg" alt="alt text"
side info: Just below above image tag I am also having no-script tag with below image tag to support non-JavaScript situation.
img src="/images/actual-image.jpg" alt="alt text"
For the purpose of brevity I didn't add any css or html in the snippet. Sorry.
Working JavaScript:
var lazy = [];
registerListener('load', setLazy);
registerListener('load', lazyLoad);
registerListener('scroll', lazyLoad);
registerListener('resize', lazyLoad);
function setLazy(){
lazy = document.getElementsByClassName('lazy');
}
function lazyLoad(){
for(var i=0; i<lazy.length; i++){
if(isInViewport(lazy[i])){
if (lazy[i].getAttribute('data-src')){
lazy[i].src = lazy[i].getAttribute('data-src');
lazy[i].removeAttribute('data-src');
}
}
}
cleanLazy();
}
function cleanLazy(){
lazy = Array.prototype.filter.call(lazy, function(l){ return l.getAttribute('data-src');});
}
function isInViewport(el){
var rect = el.getBoundingClientRect();
return (
rect.bottom >= 0 &&
rect.right >= 0 &&
rect.top <= (window.innerHeight || document.documentElement.clientHeight) &&
rect.left <= (window.innerWidth || document.documentElement.clientWidth)
);
}
function registerListener(event, func) {
if (window.addEventListener) {
window.addEventListener(event, func);
} else {
window.attachEvent('on' + event, func);
}
}
Technically the lazy load script takes the image url in the data-src attribute and replace it in the src attribute for the images shown within the viewport window.
Need/Requirement:
when I print the web page I would like to see all the images in the print (either pdf/physical printed sheet).
Issue:
Unless the user scrolls through the entire set of images, there will be blank or black placeholders (based on different browsers).
I would like to avoid above situation. I can't disable the script. So I have modified it to support print media detection and load all the images even when the user doesn't need to scrolls through the entire lazy load images.
Here is my non working script. The script need a fix.
var lazy = [];
registerListener('load', setLazy);
registerListener('load', checkPrintMedia);
registerListener('scroll', lazyLoad);
registerListener('resize', lazyLoad);
function setLazy(){
lazy = document.getElementsByClassName('lazy');
}
function checkPrintMedia(){
if (window.matchMedia) {
var mediaQueryList1 = window.matchMedia('print');
mediaQueryList1.addListener(function(mql) {
if (mql.matches) {
for(var i=0; i<lazy.length; i++){
if (lazy[i].getAttribute('data-src')){
lazy[i].src = lazy[i].getAttribute('data-src');
lazy[i].removeAttribute('data-src');
}
}
cleanLazy();
}
else{
lazyLoad();
}
});
}
}
function lazyLoad(){
for(var i=0; i<lazy.length; i++){
if(isInViewport(lazy[i])){
if (lazy[i].getAttribute('data-src')){
lazy[i].src = lazy[i].getAttribute('data-src');
lazy[i].removeAttribute('data-src');
}
}
}
cleanLazy();
}
function cleanLazy(){
lazy = Array.prototype.filter.call(lazy, function(l){ return l.getAttribute('data-src');});
}
function isInViewport(el){
var rect = el.getBoundingClientRect();
return (
rect.bottom >= 0 &&
rect.right >= 0 &&
rect.top <= (window.innerHeight || document.documentElement.clientHeight) &&
rect.left <= (window.innerWidth || document.documentElement.clientWidth)
);
}
function registerListener(event, func) {
if (window.addEventListener) {
window.addEventListener(event, func);
} else {
window.attachEvent('on' + event, func);
}
}
I need help. Please.