简体   繁体   English

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

[英]Intersection observer to detect in viewport Images in the overflow scroll container not working

Intersection observer is firing event for all the image in the overflow scroll container not when they come in the view port.交叉点观察者正在为溢出滚动容器中的所有图像触发事件,而不是当它们进入视口时。

Using the intersection observer to lazy load images: https://deanhume.com/home/blogpost/lazy-loading-images-using-intersection-observer/10163使用相交观察器延迟加载图像: 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/ https://jsfiddle.net/anshuPurohit/h84k9zkv/

The good news is your intersection observer is working.好消息是您的交叉路口观察员正在工作。 I haven't tested all of your methods, but I did get it to behave the way you want it to in your example fiddle.我还没有测试过你的所有方法,但我确实让它按照你在示例小提琴中想要的方式运行。 You need to set at least a min-width on the images.您需要在图像上至少设置一个最小宽度。 Since images are embedded content, their initial width is going to be 0. And the intersection observer makes its calculations before your images load, which means all of those elements will be visible to it when it runs.由于图像是嵌入的内容,它们的初始宽度将为 0。交叉观察者在您的图像加载之前进行计算,这意味着所有这些元素在它运行时都将可见。

You also currently have your threshold set very low.您目前也将阈值设置得非常低。 Your current threshold of '0.01' means that only 1% of the element needs to be visible for the callback to execute.您当前的阈值 '0.01' 意味着只有 1% 的元素需要可见才能执行回调。 I would recommend setting it at '0.25' and experiment with it from there.我建议将其设置为 '0.25' 并从那里开始试验。

Tl;dr. Tl;博士。 Increase your threshold, set a min-width on the image and see how it goes.增加阈值,在图像上设置最小宽度,然后看看效果如何。

One other recommendation for your image scroller, which will help maintain responsive images without resorting to assigning an explicit width to your images, is to use an intrinsic placeholder.对于图像滚动条的另一项建议是使用内在占位符,这将有助于维护响应式图像而无需为图像分配显式宽度。 http://daverupert.com/2015/12/intrinsic-placeholders-with-picture/ http://daverupert.com/2015/12/intrinsic-placeholders-with-picture/

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM