首页 > 解决方案 > 滚动时将其他文件中的 HTML 动态加载到页面上

问题描述

编辑:我已经回答了一半我自己的问题,但仍然需要帮助。请参阅下方滚动时将其他文件中的 HTML 动态加载到页面上

原始帖子: 我正在为会员改造一个包含可用于营销目的的图片库的网站。以前每个类别都分为子类别,导致几百页,有些页面只有一个图像。我已经放弃了子类别,并在每个类别页面上包含了所有图像。当您单击缩略图时,完整尺寸的图像会在灯箱中打开,其中包含其他信息

这对于大多数类别来说都很好,但有些类别很大并且包含几百张图像。问题是在这些页面上,大多数时候并不是所有的缩略图都会加载。我不想使用分页将这些大类别分成多个页面,而是希望在您向下滚动时动态加载更多内容。我不知道该怎么做。

jQuery上的代码片段在滚动上加载更多数据看起来可以工作,但是有没有办法替换

html += '<p class="dynamic">Dynamic Data : This is test data.<br />Next line.</p>';

有什么东西可以把 的内容file1.html放在它的位置,然后是file2.html,等等?

如果没有,是否有某种方法可以创建某种文件,该文件具有可以在用户向下滚动时引用和加载的缩略图位置?

这个YouTube 视频似乎是一个很好的起点,但它需要 AJAX 调用或其他调用。我不确定这意味着什么以及它在哪里调用。

标签: javascripthtmllazy-loadingdynamic-loading

解决方案


因此,感谢deanhume.com ,我找到了使用 IntersectionObserver 的潜在解决方案。它在 Chrome 和更新版本的 Firefox 中运行良好。

遗憾的是,我们仍然使用 IE 11 作为我们的标准来编码我们的站点工作。我不知道为什么,但我们这样做了,我必须处理这个问题。问题是这个解决方案不适用于我用于验证的旧版本的 Firefox,也不适用于 IE 11。所以我想使用 polyfill。

polyfill的GitHub页面讨论了使用<script src="https://polyfill.io/v3/polyfill.min.js?features=IntersectionObserver"></script>旧浏览器支持,但它似乎不起作用。我还将 polyfill JavaScript 文件放在网站上,并在任何其他 Javascript 之前在页头中引用它,但它似乎也不起作用。

加载 polyfill 文件的正确方法是什么?

引用它的第一行是:<script src="../pathto/polyfills/intersectionobserver.js"></script>

然后在进入 Intersection Observer 位之前有一些不相关的东西;用于淡入和调用延迟加载脚本的 CSS:

  <style>
    .fade-in {
      animation-name: fadeIn;
      animation-duration: 1.3s;
      animation-timing-function: cubic-bezier(0, 0, 0.4, 1);
      animation-fill-mode: forwards;
    }

    @keyframes fadeIn {
      from {
        opacity: 0;
      }

      to {
        opacity: 1;
      }
    }

.centered {
   display:block;
   margin:0 auto;
}
  </style>

  <script type="module">
    import LazyLoad from "../pathto/lazy-load.js";
    LazyLoad.init();
  </script>

下面是lazy-load.js 文件。

const defaults = {
  imageLoadedClass: 'js-lazy-image--handled',
  imageSelector: '.js-lazy-image',
  // If the image gets within 100px in the Y axis, start the download.
  rootMargin: '100px 0px',
  threshold: 0.01
};

let config,
    images,
    imageCount,
    observer;

/**
 * Fetches 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) {
    disconnect();
    return;
  }

  // Loop through the entries
  for (let i = 0; i < entries.length; i++) {
    let entry = entries[i];
    // Are we 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(config.imageLoadedClass);
  img.src = src;
}

let LazyLoad = {

  init: (options) => {
    config = {...defaults, ...options};

    images = document.querySelectorAll(config.imageSelector);
    imageCount = images.length;

    // 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(config.imageLoadedClass)) {
          continue;
        }

        observer.observe(image);
      }
    }
  }
};

export default LazyLoad;

以防万一,页面上的图像代码示例:

<img class="js-lazy-image" data-src="url/members/thumbs/ab_banff_np.jpg" alt="rockies, rocky mountains, trees, summer" aria-describedby="image_g2">


推荐阅读