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

下面是关于 "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日

相关文章

  • 详解Spring 参数验证@Validated和@Valid的区别

    详解Spring 参数验证@Validated和@Valid的区别 在Spring框架中,参数验证是一项重要的功能,用于确保传递给方法的参数满足特定的条件。Spring提供了两个注解来实现参数验证:@Validated和@Valid。尽管它们的名称相似,但它们在使用和功能上有一些区别。 @Validated注解 @Validated注解是Spring框架提供…

    other 2023年7月28日
    00
  • Android自定义封装banner组件

    下面是关于“Android自定义封装banner组件”的完整攻略及示例说明: 一、需求分析 首先需要明确的是,我们要完成一个可以实现轮播功能的banner组件,封装成库方便项目使用。在项目实现中需要考虑到以下要求: 能够自动轮播,滑动时停止轮播,松手后恢复自动轮播。 支持手动轮播,用户可以通过滑动手势进行轮播(滑动过程中不断切换banner)。 支持网络图片…

    other 2023年6月25日
    00
  • apache安装与配置

    Apache安装与配置 安装Apache 在Linux上安装 在Linux系统中,可以使用包管理器来安装Apache。以基于Debian的系统为例,可以执行以下命令来安装Apache: sudo apt-get update sudo apt-get install apache2 在Windows上安装 在Windows系统中,可以直接从Apache官网下…

    其他 2023年3月29日
    00
  • Android5.1系统通过包名给应用开放系统权限的方法

    Android 5.1系统通过包名给应用开放系统权限的方法攻略 在Android 5.1系统中,可以通过以下步骤给应用开放系统权限: 确定应用的包名:首先,需要确定要给应用开放权限的包名。包名是应用在Android系统中的唯一标识符,可以在应用的清单文件(AndroidManifest.xml)中找到。 编辑系统权限配置文件:接下来,需要编辑系统权限配置文件…

    other 2023年9月7日
    00
  • Win11 Canary Build 25387.1200预览版今日发布: 主要用于测试服务管道

    Win11 Canary Build 25387.1200预览版攻略 Win11 Canary Build 25387.1200是Windows 11操作系统的预览版之一,旨在测试服务管道的功能和稳定性。本攻略将详细介绍如何安装和使用该预览版,并提供两个示例说明。 步骤1:准备工作 在开始之前,请确保你已经满足以下要求: 一台兼容的计算机,满足Windows…

    other 2023年8月3日
    00
  • Android SDK命令行工具Monkey参数及使用解析

    Android SDK命令行工具Monkey参数及使用解析攻略 简介 Android SDK提供了一个命令行工具Monkey,用于进行Android应用程序的压力测试和随机事件生成。Monkey可以模拟用户的随机操作,帮助开发人员发现应用程序中的潜在问题。 Monkey参数 Monkey命令行工具有多个参数,用于控制测试的行为和范围。以下是一些常用的参数: …

    other 2023年9月7日
    00
  • 有关Server.Mappath详细接触

    下面是关于Server.MapPath的详细讲解: 什么是Server.MapPath Server.MapPath是一个ASP.NET中的常用方法,可以在服务器上定位一个虚拟路径对应的物理路径。虚拟路径指的是相对于当前网站根目录的路径,而物理路径指的是当前网站文件夹在服务器上的真实路径。 如何使用Server.MapPath 要使用Server.MapPa…

    other 2023年6月27日
    00
  • 苹果iOS9.3.3开发者预览版/公测版Beta5固件更新 今日推送

    苹果iOS9.3.3开发者预览版/公测版Beta5固件更新攻略 苹果iOS系统是目前移动设备上最为流行的操作系统之一,同时苹果也定期推送系统更新来修复已知的问题和改善用户体验。本文将介绍如何更新苹果iOS9.3.3开发者预览版/公测版Beta5固件。 步骤一:备份数据 任何系统更新都有一定的风险,因此我们强烈建议您在开始更新之前备份您设备上的所有数据。您可以…

    other 2023年6月26日
    00
合作推广
合作推广
分享本页
返回顶部