javascript瀑布流式图片懒加载实例

yizhihongxing

下面是关于 "javascript瀑布流式图片懒加载实例" 的完整攻略:

概述

本文将讲述如何使用 JavaScript 实现瀑布流式图片懒加载,以及如何实现懒加载动画效果。瀑布流是一种瀑布般的布局方式,能够有效节省页面空间,而懒加载则是一种优化网站性能的常用方法,能够有效减少页面初次加载的时间。

实现步骤

  1. 首先,需要在 HTML 文件中添加一个装载图片的容器,通常使用 div 标签。如下所示:
<div id="imageContainer">
  <!--图片显示区域-->
</div>
  1. 在 JavaScript 中获取该容器并创建需要的变量。
const imageContainer = document.getElementById('imageContainer');
let images = [];
let current = 0;
let limit = 20; // 一次加载几张图片
let imageWidth = 200; //图片的宽度
let imageHeight = 0; //图片的高度
let columnCount = 3; //瀑布流的列数
let loading = false; //加载完成标志
  1. 创建一个获取图片信息的函数,获取图片的宽度和高度信息。
function getImageInfo(image) {
  return new Promise((resolve, reject) => {
    const img = new Image();
    img.onload = () => {
      // 返回图片的宽、高。
      resolve({
        width: img.width,
        height: img.height
      });
    };
    img.onerror = reject;
    img.src = image.src;
  });
}
  1. 创建一个函数,用于按瀑布流式布局展示图片。
function waterfall() {
  // 计算容器的宽度和每列的宽度
  const containerWidth = imageContainer.offsetWidth;
  const columnWidth = parseInt(containerWidth / columnCount);
  //高度数组,记录每列的高度
  const heightArr = new Array(columnCount).fill(0);

  for (let i = current; i < current + limit; i++) {
    //判断是否已经全部加载完毕
    if (i >= images.length) {
      loading = false;
      return;
    }

    // 创建图片所在的容器
    const imageItem = document.createElement('div');
    imageItem.className = 'image-item';
    imageItem.style.width = imageWidth + 'px';

    //创建图片标签
    const image = document.createElement('img');
    image.src = images[i].src;
    image.dataset.index = i;

    //计算下载完成后的图片的高度
    getImageInfo(image).then((result) => {
      imageHeight = parseInt(imageWidth * result.height / result.width);

      //根据高度和高度数组,计算图片位置
      const idx = getMinHeightIndex(heightArr);
      const left = idx * columnWidth;
      const top = heightArr[idx];

      //设置图片样式和属性
      image.style.width = imageWidth + 'px';
      image.style.height = imageHeight + 'px';
      image.style.left = left + 'px';
      image.style.top = top + 'px';
      //记录该列的高度
      heightArr[idx] += imageHeight;

      //绑定图片点击事件
      image.addEventListener('click', function () {
        console.log('你点击了第' + this.dataset.index + '张图片。');
      });

      //把该图片添加到容器中
      imageItem.append(image);
      imageContainer.append(imageItem);
    });
  }

  // 根据总高度调整容器高度
  const containerHeight = Math.max.apply(null, heightArr);
  imageContainer.style.height = containerHeight + 'px';

  //增加计数器
  current += limit;
}
  1. 创建一个函数,用于获取当前高度最小的列序号。
function getMinHeightIndex(arr) {
  let index = 0;
  let minHeight = arr[0];
  for (let i = 1; i < arr.length; i++) {
    if (arr[i] < minHeight) {
      minHeight = arr[i];
      index = i;
    }
  }
  return index;
}
  1. 创建一个触发懒加载的函数。
function checkScroll() {
  const scrollTop = document.documentElement.scrollTop || document.body.scrollTop;
  const clientHeight = document.documentElement.clientHeight || document.body.clientHeight;
  const scrollHeight = document.documentElement.scrollHeight || document.body.scrollHeight;

  if (scrollTop + clientHeight >= scrollHeight - 50 && !loading) {
    loading = true;
    //进行瀑布流式布局展示图片
    waterfall();
  }
}
  1. 监听滚动事件,当滚动到页面底部时,进行懒加载。
window.addEventListener('scroll', function () {
  checkScroll();
});
  1. 最后,在 CSS 中添加样式。
#imageContainer {
  position: relative;
}

.image-item {
  position: absolute;
  transition: opacity 0.5s;
}

示例1

假设我们有一组图片 image1.jpg ~ image30.jpg,这些图片的宽度和高度不一,我们希望按照瀑布流式布局展示图片,同时采用懒加载方式加载图片,还想通过添加动画效果来使图片加载更加流畅。

<!--html-->
<div id="imageContainer"></div>

<!--css-->
<style>
#imageContainer {
  position: relative;
}

.image-item {
  position: absolute;
  transition: opacity 0.5s;
}
</style>

<!--javascript-->
<script>
const imageContainer = document.getElementById('imageContainer');
let images = [];
let current = 0;
let limit = 20;
let imageWidth = 200;
let imageHeight = 0;
let columnCount = 3;
let loading = false;

//获取图片信息函数
function getImageInfo(image) {
  return new Promise((resolve, reject) => {
    const img = new Image();
    img.onload = () => {
      resolve({
        width: img.width,
        height: img.height
      });
    };
    img.onerror = reject;
    img.src = image.src;
  });
}

//瀑布流式布局函数
function waterfall() {
  const containerWidth = imageContainer.offsetWidth;
  const columnWidth = parseInt(containerWidth / columnCount);
  const heightArr = new Array(columnCount).fill(0);

  for (let i = current; i < current + limit; i++) {
    if (i >= images.length) {
      loading = false;
      return;
    }

    const imageItem = document.createElement('div');
    imageItem.className = 'image-item';
    imageItem.style.width = imageWidth + 'px';

    const image = document.createElement('img');
    image.src = images[i].src;
    image.dataset.index = i;
    getImageInfo(image).then((result) => {
      imageHeight = parseInt(imageWidth * result.height / result.width);

      const idx = getMinHeightIndex(heightArr);
      const left = idx * columnWidth;
      const top = heightArr[idx];

      image.style.width = imageWidth + 'px';
      image.style.height = imageHeight + 'px';
      image.style.left = left + 'px';
      image.style.top = top + 'px';

      heightArr[idx] += imageHeight;

      image.addEventListener('click', function () {
        console.log('你点击了第' + this.dataset.index + '张图片。');
      });

      imageItem.append(image);
      imageContainer.append(imageItem);
      imageItem.style.opacity = 1;
    });
  }

  const containerHeight = Math.max.apply(null, heightArr);
  imageContainer.style.height = containerHeight + 'px';

  current += limit;
}

//获取当前高度最小的列数
function getMinHeightIndex(arr) {
  let index = 0;
  let minHeight = arr[0];
  for (let i = 1; i < arr.length; i++) {
    if (arr[i] < minHeight) {
      minHeight = arr[i];
      index = i;
    }
  }
  return index;
}

//触发懒加载
function checkScroll() {
  const scrollTop = document.documentElement.scrollTop || document.body.scrollTop;
  const clientHeight = document.documentElement.clientHeight || document.body.clientHeight;
  const scrollHeight = document.documentElement.scrollHeight || document.body.scrollHeight;

  if (scrollTop + clientHeight >= scrollHeight - 50 && !loading) {
    loading = true;
    waterfall();
  }
}

//监听页面滚动事件
window.addEventListener('scroll', function () {
  checkScroll();
});

//加载图片
for (let i = 1; i <= 30; i++) {
  images.push({
    src: 'image' + i + '.jpg'
  });
}
</script>

示例2

接下来,我们添加一个懒加载动画效果,让图片加载更显流畅。

<!--html-->
<div id="imageContainer"></div>

<!--css-->
<style>
#imageContainer {
  position: relative;
}

.image-item {
  position: absolute;
  transition: opacity 0.5s;
}

.loader {
  width: 30px;
  height: 30px;
  border: 5px solid #f3f3f3;
  border-top-color: #3498db;
  border-radius: 50%;
  animation: spin 2s linear infinite;
  position: absolute;
  left: 50%;
  top: 50%;
  margin-left: -15px;
  margin-top: -15px;
}

@keyframes spin {
  from {
    transform: rotate(0deg);
  }
  to {
    transform: rotate(360deg);
  }
}
</style>

<!--javascript-->
<script>
const imageContainer = document.getElementById('imageContainer');
let images = [];
let current = 0;
let limit = 20;
let imageWidth = 200;
let imageHeight = 0;
let columnCount = 3;
let loading = false;

//获取图片信息函数
function getImageInfo(image) {
  return new Promise((resolve, reject) => {
    const img = new Image();
    img.onload = () => {
      resolve({
        width: img.width,
        height: img.height
      });
    };
    img.onerror = reject;
    img.src = image.src;
  });
}

//瀑布流式布局函数
function waterfall() {
  const containerWidth = imageContainer.offsetWidth;
  const columnWidth = parseInt(containerWidth / columnCount);
  const heightArr = new Array(columnCount).fill(0);

  for (let i = current; i < current + limit; i++) {
    if (i >= images.length) {
      loading = false;
      return;
    }

    const imageItem = document.createElement('div');
    imageItem.className = 'image-item';
    imageItem.style.width = imageWidth + 'px';

    const image = document.createElement('img');
    image.src = images[i].src;
    image.dataset.index = i;

    //添加加载动画
    const loader = document.createElement('div');
    loader.className = 'loader';
    imageItem.append(loader);

    getImageInfo(image).then((result) => {
      imageHeight = parseInt(imageWidth * result.height / result.width);

      const idx = getMinHeightIndex(heightArr);
      const left = idx * columnWidth;
      const top = heightArr[idx];

      image.style.width = imageWidth + 'px';
      image.style.height = imageHeight + 'px';
      image.style.left = left + 'px';
      image.style.top = top + 'px';

      heightArr[idx] += imageHeight;

      image.addEventListener('click', function () {
        console.log('你点击了第' + this.dataset.index + '张图片。');
      });

      imageItem.append(image);
      imageContainer.append(imageItem);
      imageItem.style.opacity = 1;
      //移除加载动画
      imageItem.removeChild(loader);
    });
  }

  const containerHeight = Math.max.apply(null, heightArr);
  imageContainer.style.height = containerHeight + 'px';

  current += limit;
}

//获取当前高度最小的列数
function getMinHeightIndex(arr) {
  let index = 0;
  let minHeight = arr[0];
  for (let i = 1; i < arr.length; i++) {
    if (arr[i] < minHeight) {
      minHeight = arr[i];
      index = i;
    }
  }
  return index;
}

//触发懒加载
function checkScroll() {
  const scrollTop = document.documentElement.scrollTop || document.body.scrollTop;
  const clientHeight = document.documentElement.clientHeight || document.body.clientHeight;
  const scrollHeight = document.documentElement.scrollHeight || document.body.scrollHeight;

  if (scrollTop + clientHeight >= scrollHeight - 50 && !loading) {
    loading = true;
    waterfall();
  }
}

//监听页面滚动事件
window.addEventListener('scroll', function () {
  checkScroll();
});

//加载图片
for (let i = 1; i <= 30; i++) {
  images.push({
    src: 'image' + i + '.jpg'
  });
}
</script>

这就是实现 "javascript瀑布流式图片懒加载实例" 的完整攻略。相信在这份攻略的指引下,您可以轻松地实现瀑布流式图片懒加载的效果,并增加一些流畅的动画效果。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:javascript瀑布流式图片懒加载实例 - Python技术站

(0)
上一篇 2023年6月25日
下一篇 2023年6月25日

相关文章

  • 资讯网站解决方案

    资讯网站解决方案 对于一个资讯网站,我们需要考虑以下几方面的解决方案,以确保网站的稳定、安全和易用性。 选择合适的服务器 一台良好的服务器是保证网站正常运行的关键,我们需要选择以下几方面来确定服务器: 服务器类型:推荐选择云服务器,因为它们提供了高性能、高可靠性、易扩展性和灵活性。 操作系统:Linux服务器更加稳定和安全,而且配合LAMP(Linux、Ap…

    other 2023年6月26日
    00
  • 详解C++ string常用截取字符串方法

    详解C++ string常用截取字符串方法 在C++中,string类型是一个非常常用的数据类型,它可以存储字符串并提供一系列字符串处理的方法。其中,截取字符串是string的常见操作之一。下面是C++ string常用的截取字符串方法: 方法一:使用substr函数 substr函数可以截取字符串中的任意一段子串,其参数为子串截取的开始位置和长度,其函数原…

    other 2023年6月20日
    00
  • opencv-python小白笔记(16)

    以下是关于“OpenCV-Python小白笔记(16)”的完整攻略,包含两个示例。 OpenCV-Python小白笔记(16) OpenCV-Python是一个基于Python的开源计算机视觉库,可以用于图像处理、计算机视觉和机器学习等领域。以下是关于OpenCV-Python的一些小白笔记。 1. 读取和显示图像 我们可以使用OpenCV-Python读取…

    other 2023年5月9日
    00
  • qt|菜鸟起飞简单教程

    Qt|菜鸟起飞简单教程 Qt是一个跨平台的C++应用程序开发框架,它可以用于开发桌面应用程序、移动应程序和嵌入式应用程序等。本教程介绍如何使用Qt开发应用程序,包括以下内容: 下载和安装Qt 创建Qt项目 编写Qt代码 编译和运行Qt项目 示例说明 1. 下载和安装Qt 首先,我们需要从Qt官网下载Qt的安装程序。下载完成双击安装程序按照提示安装。 2. 创…

    other 2023年5月7日
    00
  • 自动输出类的字段值实用代码分享

    标题:自动输出类的字段值实用代码分享 介绍 本篇文章将详细讲解如何使用 Python 代码自动输出类的字段值,这对于数据处理和分析非常实用。通过本文的分享,读者可以掌握如何使用 Python 代码遍历类的所有字段,并将其输出保存。 准备 在开始本篇文章的实现之前,需要先安装 Python 的相关依赖库,如 pandas 及 openpyxl: pip ins…

    other 2023年6月26日
    00
  • tomcat9与tomcat8区别

    以下是关于Tomcat9与Tomcat8区别的详细攻略: Tomcat9与Tomcat8区别 Tomcat9和Tomcat8是Apache Tomcat服务器的两个版本。虽然它们都是Java Servlet容,但它们之间存在一些区别。 以下是Tomcat9和Tomcat8之间的一些区别: 版本:Tomcat9Java 8或更高版本,而Tomcat8需要Jav…

    other 2023年5月7日
    00
  • 浅谈C++ 类的实例中 内存分配详解

    浅谈C++ 类的实例中 内存分配详解 在C++中,类的实例化涉及到内存的分配和管理。本文将详细讲解C++类的实例中的内存分配过程,并提供两个示例来说明。 内存分配过程 当我们创建一个类的实例时,内存分配过程主要包括以下几个步骤: 分配内存空间:首先,系统会根据类的定义,确定需要分配多少内存空间来存储该类的实例。这个内存空间通常包括类的成员变量和一些额外的管理…

    other 2023年8月1日
    00
  • 微信公众平台通用接口api指南

    微信公众平台通用接口api指南 微信公众平台是一个常用的社交平台,许多企业和个人都在上面拥有自己的公众号,来进行推广和营销。为了更好地与用户互动,许多公众号都会接入微信公众平台提供的通用接口API。 API介绍 微信公众平台通用接口API是一套基于HTTP/HTTPS协议的接口,可用于进行微信公众号的开发和功能增强。API集成了许多有用的功能,例如自定义菜单…

    其他 2023年3月29日
    00
合作推广
合作推广
分享本页
返回顶部