kl-waterfall 瀑布流

2023-05-16

文章目录

    • 使用
    • 实现
      • waterfall index文件
      • kl-waterfall-item

使用

  <kl-waterfall
    @touchBottom="touchBottom"
    :distant="50"
    :cope="4"
    :margin="10"
    :sleep="200"
  >
    <kl-waterfall-item v-for="(item, index) in state.imgs" :key="index" border>
      <div class="item">
        <img :src="item.url" alt="" />
        <p>
          {{ item.content }}
        </p>
      </div>
    </kl-waterfall-item>
  </kl-waterfall>

实现

waterfall index文件

<template>
  <div class="kl-waterfall" ref="waterRef">
    <slot></slot>
  </div>
</template>
<script lang="ts" setup>
import {
  onMounted,
  reactive,
  ref,
  onBeforeUpdate,
  onBeforeUnmount,
} from "vue-demi";

import { throttle } from "../../utils/tool";

const props = defineProps({
  cope: {
    // 份数
    type: Number,
    default: 5,
    required: false,
  },
  margin: {
    // 每份的间隔
    type: Number,
    default: 10,
    required: false,
  },
  sleep: {
    // 默认延时加载 建议图片越多,值越大
    type: Number,
    default: 200,
    required: false,
  },
  distant: {
    // 距离多远触底 就触发 触底回调
    type: Number,
    default: 200,
    required: false,
  },
});

const emits = defineEmits(["touchBottom"]);

const waterRef = ref();

interface i_state {
  childWidth: number; // 每项的公共宽度
  heightArr: number[]; // 存储每列的高度数组
  max: number; // 当前的最高项的高度
  top: number; // 当前kl-waterfall 距离顶部的距离
  clientHeight: number; // 可视区高度
  isBottom: boolean; // 是否到了底部
  lastLength: number; // 上次的长度
  timer: any; // 记录timer
}
const state = reactive<i_state>({
  childWidth: 0,
  heightArr: [],
  max: 0,
  top: 0,
  clientHeight: 0,
  isBottom: false,
  lastLength: 0,
  timer: null,
});

// 滚动事件
const handleScroll = throttle(() => {
  //scrollTop就是触发滚轮事件时滚轮的高度
  var scrollTop = document.documentElement.scrollTop || document.body.scrollTop;
  // console.log(scrollTop + state.clientHeight);

  if (
    state.max + state.top <= scrollTop + state.clientHeight + props.distant &&
    !state.isBottom
  ) {
    state.isBottom = true;
    emits("touchBottom", {
      code: 200,
      msg: "触底了",
    });
  }
}, 50);

onMounted(() => {
  const width = waterRef.value.clientWidth;
  state.top = waterRef.value.offsetTop;
  state.clientHeight = document.documentElement.clientHeight;

  // 每个子元素的宽度
  let childWidth = Math.ceil(
    (width - (props.cope + 1) * props.margin) / props.cope
  );

  state.childWidth = childWidth;

  // 开始处理业务
  handleEvent();

  // 添加触底事件
  window.addEventListener("scroll", handleScroll, true);
});

onBeforeUnmount(() => {
  clearTimeout(state.timer);
  state.timer = null;
});

// 具体处理相关的业务
function handleEvent() {
  // console.log(state.lastLength);
  clearTimeout(state.timer);
  state.timer = null;

  state.timer = setTimeout(() => {
    // 给每个子项设宽
    let childs = waterRef.value.children;
    // console.log(childs.length);

    let childLength = childs.length;

    for (let i = state.lastLength; i < childLength; i++) {
      childs[i].style.width = state.childWidth + "px";
    }
    state.isBottom = false;
    // 获取每个元素的高
    for (let i = state.lastLength; i < childLength; i++) {
      let height: number = Number(childs[i].offsetHeight) || 0;
      // console.log(height);

      // 第一排设置
      if (i < props.cope) {
        childs[i].style.top = props.margin + "px";
        childs[i].style.left =
          (i + 1) * props.margin + i * state.childWidth + "px";
        state.heightArr.push(props.margin + height);
        // console.log("kkk");
      } else {
        // 找到最小项
        let minHeight = Math.min(...state.heightArr);

        // 找到最小项的index
        let minHeightIndex = state.heightArr.findIndex((item) => {
          return item == minHeight;
        });

        childs[i].style.top =
          state.heightArr[minHeightIndex] + props.margin + "px";
        childs[i].style.left =
          (minHeightIndex + 1) * props.margin +
          minHeightIndex * state.childWidth +
          "px";
        state.heightArr[minHeightIndex] = minHeight + props.margin + height;
      }
    }

    // 重新给父元素定高度
    let max = Math.max(...state.heightArr);
    state.max = max;
    waterRef.value.style.height = max + props.margin + "px";
    // 记录下当前的长度

    state.lastLength = childLength;
  }, props.sleep);
}

// 当数据更新时的业务
onBeforeUpdate(() => {
  handleEvent();
});
</script>
<style lang="scss" scoped>
.kl-waterfall {
  display: block;
  position: relative;
}

.kl-loading {
  height: 50px;
  text-align: center;
  color: #666;
}
</style>

kl-waterfall-item

<template>
  <div
    :class="[
      'kl-clearFix',
      'kl-waterfall-item',
      border ? 'kl-waterfall-item-border' : '',
    ]"
  >
    <slot />
  </div>
</template>
<script lang="ts" setup>
defineProps({
  border: {
    type: Boolean,
    default: false,
    required: false,
  },
});
</script>

<style lang="scss" scoped>
.kl-waterfall-item-border {
  box-shadow: 0 0 5px #555;
  display: block;
  position: absolute;
}
</style>
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

kl-waterfall 瀑布流 的相关文章

  • 面试必问的红黑树,从根源上探究红黑树的本质

    前言 本文主要讲解下面试经常会问到的红黑树 xff0c 看看究竟是什么神仙鬼怪 二叉树 满足以下两个条件的树就是二叉树 xff1a 本身是有序树 xff08 若将树中每个结点的各子树看成是从左到右有次序的 即不能互换 xff0c 则称该树为
  • C++后台开发面试题总结(涉及C++基础、多线程多进程、网络编程等)

    C 43 43 后台开发面试题总结 涉及C 43 43 基础知识 多线程多进程 TCP IP网络编程 Linux操作 数据结构与算法 因巩固知识体系 xff0c 面试 xff0c 梳理以往看到过的知识点 xff0c 故总结如下相关题目 xf
  • 实战项目:手把手带你实现一个高并发内存池

    项目介绍 1 这个项目做的是什么 xff1f 当前项目是实现一个高并发的内存池 xff0c 他的原型是google的一个开源项目tcmalloc xff0c tcmalloc全称Thread Caching Malloc xff0c 即线程
  • HTTP keep-alive和TCP keepalive的区别,你了解吗?

    1 从文中找出我的IP 2 http请求中是客服端还是服务端主动关闭的tcp连接 xff1f 请阅读到最后的彩蛋部分 HTTP和TCP都是老生常谈的知识点 xff0c 本文不进行铺开赘述 我们可能在HTTP和TCP中都听说 长连接 的说法
  • Linux下各种锁的理解和使用及总结解决epoll惊群问题(面试常考)

    一 锁 锁出现的原因 临界资源是什么 多线程执行流所共享的资源 锁的作用是什么 可以做原子操作 在多线程中针对临界资源的互斥访问 保证一个时刻只有一个线程可以持有锁对于临界资源做修改操作 任何一个线程如果需要修改 xff0c 向临界资源做写
  • 一个10年C++程序员对技术和业务的感悟,献给还在迷茫中的你

    我越来越担心我作为一个C 43 43 程序员的未来 恍然间 xff0c 发现自己在这个行业里已经摸爬滚打了十年了 xff0c 原以为自己就凭已有的项目经验和工作经历怎么着也应该算得上是一个业内比较资历的人士了 xff0c 但是今年在换工作的
  • 大专程序员毕业五年税后18K,想进BAT,网友:吃shi都赶不上热的

    现在很多互联网公司招聘程序员 xff0c 招聘要求上面都明确需要本科 xff0c 并且985 211优先 现在有很多中专大专的程序员很优秀很积极 网友一 xff1a 女生 xff0c 92年 xff0c 毕业四年 xff0c 坐标深圳 xf
  • “天才少年” 27岁华为副总裁 百度CTO 成为阶下囚的传奇经历

    今天的主角是李一男 xff0c 也许你未曾听过他的名字 xff0c 但他却有金光闪闪的履历 毕业于华中科大少年班 xff0c 最年轻的华为副总裁 xff0c 百度CTO xff0c 12580CEO xff0c 金沙江创投合伙人 xff0c
  • 计算机网络---TCP的可靠传输机制和面向字节流传输

    在了解了TCP的面向连接传输之后我们讲解TCP的可靠传输相关的机制和面向字节流传输 一 xff0c TCP的可靠传输 可靠应答机制超时重传机制报文中的序号和确认序号 可靠应答机制 就是在每次发送数据或者请求之后对方都要回复一个应答信号 xf
  • Linux内核必读五本书籍(强烈推荐)

    深入理解Linux内核 推荐等级 xff1a 5颗星 为了透彻理解Linux的工作机理 xff0c 以及为何它在各种系统上能顺畅运行 xff0c 你需要深入到内核的心脏 cPu与外部世界的所有交互活动都是由内核处理的 xff0c 哪些程序会
  • YOLO系列标注文件txt标签类别索引批量修改脚本

    在我们做YOLO类检测网络的自定义训练时 xff0c 有时会将多个独立的数据集合并训练 xff0c 但往往遇到一个问题 xff0c 比如两个独立的数据集中有相同的一类 xff0c 比如船 但是在一个数据集中船的标注文件 txt文件 的索引为
  • realsense系列(二):录制深度图和RGB图

    录制深度图和RGB图 本次任务使用方法总结 本次任务 利用realsenseviewer软件录制深度图和RGB图 使用方法 1 将realsense连接到计算机上 xff0c 然后打开realsenseviewer软件 xff0c 打开后默
  • realsense系列(三):播放深度图和RGB图

    播放深度图和RGB图 本次任务使用方法总结 本次任务 利用realsenseviewer软件播放深度图和RGB图 使用方法 1 将realsense连接上计算机 然后打开realsenseviewer软件 点击Add Source Load
  • 海思3559万能平台搭建:OSD实时叠加的支持2区域RGN的配置

    前言 位图的生成只是我们字符叠加的基础 xff0c 具体表现就要靠对区域RGN的配置了 调试记录 现在距离移植成功osd也有一段时间了 xff0c 所有所有的报错一时也想不起来太多 xff0c 当时是在焦头烂额没有记录下全部 xff0c 但
  • 在ubuntu中使用命令行下载谷歌浏览器(Linux)

    使用命令行安装谷歌 1 sudo wget http www linuxidc com files repo google chrome list P etc apt sources list d 2 wget q O https dl g
  • TJA1043 CanTrcv

    目录 一 概述 二 功能和优势 2 1 基本功能 2 2 低功耗管理 2 3 保护和诊断 xff08 检测和信号传输 xff09 三 引脚信息 四 功能描述 4 1 五种工作模式 4 1 1 正常模式 4 1 2 仅监听模式 4 1 3 待
  • Git/Gitlab添加SSH秘钥与小乌龟配置

    目录 一 Git Gitlab添加SSH秘钥 二 秘钥添加情况验证 三 小乌龟关联SSH 一 Git Gitlab添加SSH秘钥 xff08 1 xff09 查找是生成sSh秘钥 xff0c 显示文件夹不存在 xff0c 可以生成秘钥 指令
  • 系统分析师之信息化技术(十一)

    目录 一 企业信息化概述 1 1 信息系统的基本概念 1 1 1 什么是信息 1 1 2 什么是信息化 1 1 3 信息系统分类 二 企业信息化规划 2 1 信息化战略体系 2 2 企业战略与信息化战略集成方法 三 信息系统开发方法 3 1
  • 【AUTOSAR】【信息安全】SecOC

    目录 一 概述 二 约束和假设 三 依赖模块 四 功能描述 4 1 安全解决方案的规范 4 1 1 安全解决方案的基本实体 4 1 2 安全的I PDU构建 4 1 3 安全的I PDU验证 4 2 与PduR的关系 4 3 初始化 4 4
  • 计算机网络---网络层

    网络层的作用 IP地址 地址管理 路由选择 1 网络层的作用 首先网络层是为了地址管理和路由选择 xff0c 通过对地址的管理能够保证数据从一台主机上到另一台主机上 xff0c 并且选择合适的路径进行传输 主机 就是PC xff0c 也就是

随机推荐

  • 【AUTOSAR】【通信安全】CRC

    目录 一 概述 二 功能说明 2 1 通用行为 2 2 8位CRC计算 2 2 1 8位SAE J1850 CRC计算 2 2 2 8位0x2F多项式CRC计算 2 3 16位CRC计算 2 3 1 16位CCITT FALSE CRC16
  • 系统分析师之项目管理(十七)

    一 范围管理 范围管理 xff1a 确定项目的边界 xff0c 即哪些工作是项目应该做的 xff0c 哪些工作不应该包括在项目中 二 时间管理 时间管理 xff1a 也叫进度管理 xff0c 就是用科学的方法 xff0c 确定目标进度 xf
  • 【AUTOSA】

    目录 一 概述 二 限制与约束 三 功能描述 3 1 网络通信模式请求的转换 3 2 当前网络通信方式的输出 3 3 外围设备的控制 3 3 1 以太网接口控制器 3 4 多网络 3 5 网络模式状态机 3 5 1 初始化 3 5 2 在亚
  • 【AUTOSAR】【以太网】TCPIP

    目录 一 概述 二 约束和假设 三 依赖模块 3 1 EthIf 3 2 EthSM 3 3 SoAd 3 4 KeyM 3 5 CSM 四 功能说明 4 1 系统扩展性 4 2 IPv4 4 2 1 IPv4 4 2 2 ARP 4 2
  • CMake 链接时出现undefined reference to 错误

    一 问题背景 之前新建了一个项目项目文件分布为 1 src MROR cpp 2 include MROR h 3 main cpp 执行cmake出现undefined reference toxx xff0c 显示main函数中的类成员
  • Ubuntu系统下使用VScode进行CMake编译调试C++程序

    一 前提须知 必须确保你的cmake文件能够编译通过 xff0c 并可以通过make生成可执行文件 二 具体步骤 1 设置CMakeLists txt set CMAKE BUILD TYPE DEBUG 2 VScode调试 VScode
  • 基于TCP协议的Socket编程

    一 基于TCP协议的网络编程 1 TCP IP是一种可靠的网络协议 xff0c 它在通信的两端各建立一个Socket xff0c 从而在通信的两端之间形成网络虚拟链路 xff1b 一旦建立了虚拟的网络链路 xff0c 两端的程序就可以通过虚
  • 示波器抓板子串口,波形错误,杂乱无章

    示波器抓板子串口 xff0c 波形杂乱无章 在使用Hi3559芯片时 xff0c 需要实现串口输出功能 xff0c 实际抓波形时 xff0c 波形杂乱无章 xff0c 感觉很离奇 xff0c 偶然间发现原因 xff0c 在此分享一下 串口信
  • GPS经纬度坐标WGS84到东北天坐标系ENU的转换

    GPS经纬度坐标WGS84到东北天坐标系ENU的转换 常用坐标系介绍地理坐标系 Geographic Coordinate System GCS 地心地固坐标系 ECEF 当地东 北 上 ENU 坐标 基坐标相互转化地理坐标系到地心地固坐标
  • Unity学习笔记--易学易会的unity中A星寻路插件:A*Pathfind Project的使用

    A寻路看似简单 xff0c 但实际项目中的各种应用是有一定难度的 xff0c 需要较强的算法功底 xff0c 不过 xff0c 幸运的是 xff0c Unity Asset Store中已经有了现成的A寻路插件 34 A Pathfindi
  • HTTP常见面试题

    个人总结 xff0c 请勿转载 URL 统一资源定位符 xff1a 就是标识网络中资源的路径 HTTP 超文本传输协议 是一个基于TCP IP通信协议来传递信息 HTTP原理 HTTP协议工作与客户端 服务端架构上 xff0c 浏览器作为H
  • Unity开发2D游戏实现寻路算法——【PolyNav - 2D Pathfinding】插件的使用

    Navmesh2d插件的简单使用说明 2d游戏如何实现寻路算法NavMesh2d插件的简单使用方法创建2d导航网格添加寻路组件 简单实现寻路功能的脚本鼠标点击寻路自动路径寻路 Demo寻路效果效果gif xff1a demo插件下载 组件属
  • electron中使用 alert和comfirm等弹出框都会致使input无法获得焦点

    electron中使用 alert和comfirm等弹出框都会致使input无法获得焦点 解决办法 xff1a 自定义
  • v-if和v-for的优先级

    文章目录 vue2vue3 vue2 v for优先级比v if高v for与v if作用在不同标签时候 xff0c 是先进行判断 xff0c 再进行列表的渲染 注意事项 永远不要把 v if 和 v for 同时用在同一个元素上 xff0
  • nginx配置history模式路由

    对nginx配置文件 conf修改 server span class token punctuation span listen span class token number 80 span span class token punct
  • day45 Promise实现一个分批请求

    要求 100个请求 每次5个 具体实现
  • 移动端软键盘和input遮挡问题

    零时解决方案 span class token doctype span class token punctuation lt span span class token doctype tag DOCTYPE span span clas
  • 如何获取 b站视频 纯播放

    通过视频页url直接拿到 BV1NV411v7Xp https www bilibili com video BV1NV411v7Xp spm id from 61 autoNext 发起请求 拿到 aid cid https api bi
  • vue3 ts vite 配置别名 导致报 无法找到对应莫模块的错误处理方式

    第一步 vite config ts alias span class token operator span span class token punctuation span span class token string 34 64
  • kl-waterfall 瀑布流

    文章目录 使用实现waterfall index文件kl waterfall item 使用 span class token operator lt span kl span class token operator span water