延迟加载的最简单的JS仅适用于图像吗? (请不要依赖)

时间:2018-06-25 08:15:20

标签: javascript lazy-loading

寻找一种最简单的方法: 延迟加载JS以仅在投资组合网站上加载图像。

应该可以在任何浏览器上运行,请不要使用jquery,而应使用简单的纯js编码。 将img命名为CSS类“ .image-box”。

网站具有响应能力,但不要对不同的响应大小使用不同的图像源文件。

感谢我的帮助。

这是js代码,我尝试了此操作,但看不到渐进式图像加载:

$('select[name^=manufacturerCountry')

如何在html上使用它? 好吧,加载脚本然后呢?

2 个答案:

答案 0 :(得分:0)

这是我自定义的惰性加载程序,我一直打算将其作为开源版本发布,但是还没有解决。

它没有依赖关系,仅使用常规的DOM API。

它可能并不完美,但是它应该可以帮助您入门。请让我知道是否需要有关如何实现丢失的导入的指示。

import {registerViewportChangeCallback, unregisterViewportChangeCallback,
  elementInView} from './viewportHandler';
import {querySelectorAllCached} from './index';

let lazyCache = {};
let lazyCacheList = [];
let imgElements = null;
let allLoaded = false;

function removeEventListeners (el) {
  el.removeEventListener('load', onLoad);
  el.removeEventListener('error', onError);
}

function onLoad (e) {
  e.target.classList.remove('akm-lazy-loading');
  e.target.classList.add('akm-lazy-loaded');
  removeEventListeners(e.target);
}

function onError (e) {
  e.target.classList.remove('akm-lazy-loading');
  e.target.classList.add('akm-lazy-error');
  removeEventListeners(e.target);
}

function updateImages () {
  if (allLoaded) {
    return;
  }

  if (!imgElements) {
    // Find all images on the page and sort them top to bottom
    // so that we can start preloading the topmost images first
    imgElements = querySelectorAllCached(
      'img[data-src], img[data-srcset]')
      .sort((a, b) => {
        const aTop = a.getBoundingClientRect().top;
        const bTop = b.getBoundingClientRect().top;
        if (aTop < bTop) {
          return -1;
        } else if (bTop > aTop) {
          return 1;
        }
        return 0;
      });
  }

  for (let i = 0; i < imgElements.length; i++) {
    if (lazyCache[i]) {
      continue;
    }

    const el = imgElements[i];
    if (!elementInView(el)) {
      continue;
    }

    loadImage(i);
  }
}

function loadImage (i) {
  const el = imgElements[i];
  lazyCache[i] = true;
  lazyCacheList = Object.keys(lazyCache);

  if (el.src.indexOf('mno_0643') !== -1) {
    // debugger;
  }

  el.addEventListener('load', onLoad);
  el.onLoad = onLoad;
  el.addEventListener('error', onError);
  el.onError = onError;
  el.classList.add('akm-lazy-loading');

  if (el.parentElement.tagName.toLowerCase() === 'picture') {
    for (const src of
      Array.from(el.parentElement.querySelectorAll('source'))) {
      if (src.dataset.srcset) {
        src.srcset = src.dataset.srcset;
        delete src.dataset.srcset;
      }
      if (src.dataset.src) {
        src.src = src.dataset.src;
        delete src.dataset.src;
      }
    }
  }
  if (el.dataset.srcset) {
    el.srcset = el.dataset.srcset;
    delete el.dataset.srcset;
  }
  if (el.dataset.src) {
    el.src = el.dataset.src;
    delete el.dataset.src;
  }

  if (lazyCacheList.length === imgElements.length) {
    onAllLoaded();
  }
}

function onAllLoaded () {
  allLoaded = true;
  unregisterViewportChangeCallback(updateImages);
}

export function initLazyload () {
  registerViewportChangeCallback(updateImages);
}

答案 1 :(得分:0)

Intersection Observer作弊吗?

window.addEventListener("load", function (event) {
  var images = document.querySelectorAll('#lazy-img');
  //if the browser doesn't support IO
  if (!('IntersectionObserver' in window)) {
    LoadImagesOldWay(images);
  } else {
    createObserver(images);
  }
}, false);

function createObserver(images) {
  var options = {
    //root defaults
    root: null,
    rootMargin: "0px",
    //threshold is how much of the element is intersected before firing callback
    threshold: .01
  };
  //create an observer, add the options and callback function
  //then add each image to the observer.
  var observer = new IntersectionObserver(handleIntersect, options);
  images.forEach(function (image) {
    observer.observe(image);
  });

}
//load the smallest image for old browsers
function LoadImagesOldWay(images) {
  images.forEach(function (image) {
    var url = image.getAttribute('data-src');
    image.setAttribute('src', url);
  });
}

function handleIntersect(entries, observer) {
  // Loop through the entries
  entries.forEach(function (entry) {
    //if this entry is intersecting whatsoever
    if (entry.intersectionRatio > 0) {
      var image = entry.target;
      //we get our responsive image set
      var url = image.getAttribute('data-src');
      //and set them as the actual source
      image.setAttribute('src', url);
      //we unobserve (Separate) the image entirely
      observer.unobserve(entry.target);
      console.log('lazy-image loaded!:simpleIO.js line 49 to remove this!');
    }
  });
}

我喜欢IO,因为它非常健壮且开放。您可以使用交集观察器延迟加载任何东西

在我的github上查看带有响应图像的示例

编辑-哇,您错过了所有的选票。不知道为什么有人看到-1并认为它需要变得更糟。我认为这是一个好问题,只是措辞不佳。不要让他们得到你。 :D

Simple-Intersection-Observer