2017-09-25 2 views
1

L'observateur d'intersection déclenche un événement pour toute l'image dans le conteneur de défilement de débordement, et non lorsqu'elles arrivent dans le port d'affichage.Observateur d'intersection pour détecter dans la fenêtre Les images du conteneur de défilement dépassent

Utilisation de l'observateur d'intersection des images de charge paresseux: https://deanhume.com/home/blogpost/lazy-loading-images-using-intersection-observer/10163

<ul class="product-horizontal-list"> 
    <li> <img class="js-lazy-image centered" data-src="https://rukminim1.flixcart.com/image/312/312/j0vb3bk0/t-shirt/h/b/x/m-arek0253grey-melange-arrow-sports-original-imaeskqnukxhvhth.jpeg?q=70"></li> 

    <li> <img class="js-lazy-image centered" data-src="https://rukminim1.flixcart.com/image/312/312/j6dxaq80/t-shirt/h/y/u/m-28771-0061blacks-levi-s-original-imaewv46jxf4wyxa.jpeg?q=70"></li> 
    <li> <img class="js-lazy-image centered" data-src="https://rukminim1.flixcart.com/image/312/312/j7qi9ow0/t-shirt/x/r/z/m-bts026-billion-original-imaexwxvczbnfz8a.jpeg?q=70"></li> 
    <li> <img class="js-lazy-image centered" data-src="https://rukminim1.flixcart.com/image/312/312/j4hc5u80/t-shirt/u/w/j/m-17p3dtpj3033i501-united-colors-of-benetton-original-imaevcrzqas8uwvy.jpeg?q=70"></li> 
    <li> <img class="js-lazy-image centered" data-src="https://rukminim1.flixcart.com/image/312/312/j0vb3bk0/t-shirt/n/a/x/m-arek0255me-yellow-arrow-sports-original-imaeskqzm5hrn8hk.jpeg?q=70"></li> 
    <li> <img class="js-lazy-image centered" data-src="https://rukminim1.flixcart.com/image/312/312/j6pctjk0/t-shirt/v/e/8/m-akss3356navy-arrow-sport-original-imaex3xgzhjvdzxu.jpeg?q=70"></li> 
    <li> <img class="js-lazy-image centered" data-src="https://rukminim1.flixcart.com/image/312/312/j6gs6fk0/t-shirt/e/v/n/m-24608-0004blues-levi-s-original-imaewxcwweyz9fh3.jpeg?q=70"></li> 

</ul> 

    // Get all of the images that are marked up to lazy load 
const images = document.querySelectorAll('.js-lazy-image'); 
const config = { 
    // If the image gets within 50px in the Y axis, start the download. 
    rootMargin: '0px', 
    threshold: 0.01 
}; 

let imageCount = images.length; 
let observer; 

// If we don't have support for intersection observer, loads the images immediately 
if (!('IntersectionObserver' in window)) { 
    loadImagesImmediately(images); 
} else { 
    // It is supported, load the images 
    observer = new IntersectionObserver(onIntersection, config); 

    // foreach() is not supported in IE 
    for (let i = 0; i < images.length; i++) { 
    let image = images[i]; 
    if (image.classList.contains('js-lazy-image--handled')) { 
     continue; 
    } 

    observer.observe(image); 
    } 
} 

/** 
* Fetchs the image for the given URL 
* @param {string} url 
*/ 
function fetchImage(url) { 
    return new Promise((resolve, reject) => { 
    const image = new Image(); 
    image.src = url; 
    image.onload = resolve; 
    image.onerror = reject; 
    }); 
} 

/** 
* Preloads the image 
* @param {object} image 
*/ 
function preloadImage(image) { 
    const src = image.dataset.src; 
    if (!src) { 
    return; 
    } 

    return fetchImage(src).then(() => { applyImage(image, src); }); 
} 

/** 
* Load all of the images immediately 
* @param {NodeListOf<Element>} images 
*/ 
function loadImagesImmediately(images) { 
    // foreach() is not supported in IE 
    for (let i = 0; i < images.length; i++) { 
    let image = images[i]; 
    preloadImage(image); 
    } 
} 

/** 
* Disconnect the observer 
*/ 
function disconnect() { 
    if (!observer) { 
    return; 
    } 

    observer.disconnect(); 
} 

/** 
* On intersection 
* @param {array} entries 
*/ 
function onIntersection(entries) { 
    // Disconnect if we've already loaded all of the images 
    if (imageCount === 0) { 
    observer.disconnect(); 
    } 

    // Loop through the entries 
    for (let i = 0; i < entries.length; i++) { 
    let entry = entries[i]; 
    // Are we in viewport? 
    console.log('in viewport') 
    if (entry.intersectionRatio > 0) { 
     imageCount--; 

     // Stop watching and load the image 
     observer.unobserve(entry.target); 
     preloadImage(entry.target); 
    } 
    } 
} 

/** 
* Apply the image 
* @param {object} img 
* @param {string} src 
*/ 
function applyImage(img, src) { 
    // Prevent this from being lazy loaded a second time. 
    img.classList.add('js-lazy-image--handled'); 
    img.src = src; 
    img.classList.add('fade-in'); 
} 

https://jsfiddle.net/anshuPurohit/h84k9zkv/

Répondre

0

Les bonnes nouvelles sont votre observateur d'intersection fonctionne. Je n'ai pas testé toutes vos méthodes, mais je l'ai fait se comporter comme vous le voulez dans votre exemple. Vous devez définir au moins une largeur minimale sur les images. Puisque les images sont des contenus incorporés, leur largeur initiale va être 0. Et l'observateur d'intersection fait ses calculs avant que vos images ne se chargent, ce qui signifie que tous ces éléments seront visibles quand il fonctionnera.

Votre seuil actuel est également très bas. Votre seuil actuel de '0.01' signifie que seulement 1% de l'élément doit être visible pour le rappel à exécuter. Je recommande de le régler à '0.25' et de l'expérimenter à partir de là.

Tl; dr. Augmentez votre seuil, définissez une largeur minimale sur l'image et voyez comment ça se passe.

Une autre recommandation pour votre défileur d'image, qui aidera à maintenir des images réactives sans avoir recours à l'attribution d'une largeur explicite à vos images, consiste à utiliser un espace réservé intrinsèque. http://daverupert.com/2015/12/intrinsic-placeholders-with-picture/