交叉口观察者在视口中检测溢出滚动容器中的图像不起作用

时间:2017-09-25 18:00:35

标签: javascript css dom

交叉观察者正在为溢出滚动容器中的所有图像触发事件,而不是它们进入视口时。

使用交叉点观察器延迟加载图像: 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/

1 个答案:

答案 0 :(得分:1)

好消息是你的交叉口观察员正在工作。我没有测试过你的所有方法,但我确实让它在你的示例小提琴中按照你想要的方式运行。您需要在图像上至少设置一个最小宽度。由于图像是嵌入内容,因此它们的初始宽度将为0.并且交叉点观察者在图像加载之前进行计算,这意味着所有这些元素在运行时都可见。

您目前的阈值设置也非常低。您当前的阈值“0.01”表示只有1%的元素需要可见才能执行回调。我建议将其设置为'0.25'并从那里进行试验。

铊;博士。提高阈值,在图像上设置最小宽度并查看其运行方式。

图像滚动条的另一个建议是使用内在占位符来帮助维护响应图像而不需要为图像指定明确的宽度。 http://daverupert.com/2015/12/intrinsic-placeholders-with-picture/