Vue3 实现一个无缝滚动组件(支持鼠标手动滚动)
Vue3 实现一个无缝滚动组件(支持鼠标手动滚动)
前言
在日常开发中,经常遇到需要支持列表循环滚动展示,特别是在数据化大屏开发中,无缝滚动使用频率更为频繁,在jquery时代,我们常用的无缝滚动组件为liMarquee,在vue中已经有vue-seamless-scroll组件(通过Vue2实现,不支持鼠标手动滚动),但是在使用过程中,发现滚动后会存在点击事件失效的问题,并且产品提了个需求,需要支持鼠标手动滚动,也要支持自动滚动,于是痛定思痛,决定通过Vue3来实现该功能,该组件已经实现上传npm,可以直接安装使用,链接在文尾。
实现
html部分
首先写一个基础的list结构,通过插槽接收外部传入的list数据,因为需要实现无缝滚动,需要复制出同一份的Dom,在最外层监听鼠标hover和leave的状态,以实现鼠标hover暂停滚动,绑定鼠标滚动事件,在鼠标滚动时记住滚动的位置,在恢复自动滚动时能从当前滚动位置继续滚动。
<div class="custom-list" ref="scrollBody" @mouseenter="mouseenterFunc" @mouseleave="mouseleaveFunc"@mousewheel="mousewheelFunc"><div class="list-body" :class="{'list-body2': isHorizontal}" ref="listBody" :style="{ transform: getScrollDistance() }"><slot></slot></div><div class="list-body" :class="{'list-body2': isHorizontal}" ref="tBody" v-if="isCanScroll" :style="{ transform: getScrollDistance() }"><slot></slot></div>
</div>
实现逻辑
开始
通过父级传入的isHorizontal判断是横向滚动,还是垂直滚动
const start = () => {//判断是否可以滚动函数let isScrollFunc = (bodySize:number, listSize:number) => {if (bodySize > listSize) {scrollDistance.value = 0;isCanScroll.value = !1;}};isStop.value = !1;//判断是否可以滚动if (!isHorizontal.value) {isScrollFunc(bodyHeight.value, listHeight.value);} else {isScrollFunc(bodyWidth.value, listWidth.value);}if (isCanScroll.value) {run();}
}
开始滚动
计算目前滚动的距离,并判断需要滚动的方向,计算下一步滚动的距离。
const run = () => {//清空动画clearAnimation();animationFrame.value = window.requestAnimationFrame(() => {//滚动主逻辑函数let main = (listSize:number, bodySize:number) => {let tempScrollDistance = Math.abs(scrollDistance.value);if (scrollDistance.value < 0) {let cc = 2 * listSize - bodySize;if (tempScrollDistance > cc) {scrollDistance.value = -(listSize - bodySize);}} else {scrollDistance.value = -listSize;}};//根据滚动方向判断使用高度或宽度控制效果if (!isHorizontal.value) {main(listHeight.value, bodyHeight.value);} else {main(listWidth.value, bodyWidth.value);}//判断滚动值if (!isStop.value) {if (props.scrollDirection === "top" ||props.scrollDirection === "left") {scrollDistance.value -= props.steep;} else if (props.scrollDirection === "bottom" ||props.scrollDirection === "right") {scrollDistance.value += props.steep;}run();}});
}
获取滚动样式
通过translate实现列表平移,已实现平滑滚动。
const getScrollDistance = () => {let style;if (!isHorizontal.value) {style = "translate(0px, " + scrollDistance.value + "px)";} else {style = "translate(" + scrollDistance.value + "px,0px)";}return style;
}
const clearAnimation = () => {if (animationFrame.value) {cancelAnimationFrame(animationFrame.value);animationFrame.value = null;}
}
鼠标滚动
鼠标滚动时实时计算滚动的距离,可通过传入的鼠标滚动速率来计算每次滚动多少。
const mousewheelFunc = (e:any) => {if (!isCanScroll.value || !props.isRoller) {return false;}let dis = e.deltaY;if (dis > 0) {scrollDistance.value -= props.rollerScrollDistance;} else {scrollDistance.value += props.rollerScrollDistance;}run();
}
使用
该组件已上传npm仓库,欢迎satrt使用
npm install @fcli/vue-auto-scroll --save-dev 来安装在项目中使用
import VueAutoScroll from '@fcli/vue-auto-scroll';
const app=createApp(App)
app.use(VueAutoScroll);
使用示例:
<div class="content"><vue-auto-scroll :data="list" :steep="0.5" scrollDirection="top" :isRoller="true" :rollerScrollDistance="50"><div class="li" v-for="i in list" :key="i">{{ i }}</div></vue-auto-scroll>
</div>
属性 | 属性名称 | 类型 | 可选值 |
---|---|---|---|
steep | 滚动的速率 | number | 为正数即可 |
scrollDirection | 滚动的方向 | string | top ,bottom,left,right |
isRoller | 是否可以使用滚轮滚动 | boolean | true,false |
rollerScrollDistance | 滚轮滚动的速率 | number | (isRoller 必须为 true)为正数即可 |
data | 接收异步数据 | array | 同步任务可不传 |
注: 当scrollDirection 为top或bottom时,一定要为 vue-auto-scroll 组件设置高度。 当scrollDirection 为left或right时,一定要为 vue-auto-scroll 组件设置宽度。并为嵌入vue-auto-scroll中的标签设置样式为display:inline-block; 示例样式名为list-item可以更改为其他类名。当scrollDirection 为left或right时,是基于行内元素的“white-space: nowrap;” 来控制强制不换行的。有可能会影响其内部的文字排列。可以在list-item 层添加 white-space: normal; 来处理给问题。并为其添加固定宽度,以保证文字可以正常换行及插件的正确计算与显示。如果没有为其添加固定宽度,会造成插件获取父容器层的宽度值错误,导致显示混乱
git地址:https://gitee.com/fcli/vue-auto-scroll.git
相关文章:
Vue3 实现一个无缝滚动组件(支持鼠标手动滚动)
Vue3 实现一个无缝滚动组件(支持鼠标手动滚动) 前言 在日常开发中,经常遇到需要支持列表循环滚动展示,特别是在数据化大屏开发中,无缝滚动使用频率更为频繁,在jquery时代,我们常用的无缝滚动组…...

【IP数据报】IP地址和MAC地址的区别
1、用IP地址来标识Internet的主机 在每个IP数据报中,都会携带源IP地址和目标IP地址来标识该IP数据报的源和目的主机。IP数据报在传输过程中,每个中间节点(IP 网关)还需要为其选择从源主机到目的主机的合适的转发路径(即路由)。IP协议可以根据路由选择协…...
高并发笔记
如何设计一个高并发系统?:https://mp.weixin.qq.com/s/yFc-70DEhloWn0G3GDa6Yw 分布式 ID 服务实践:https://mp.weixin.qq.com/s/KAts9Zjj8JpEd0Q6pqLlgQ 一文聊透布隆过滤器:https://mp.weixin.qq.com/s/qJ2fDm1Z57bPSzOBrgiqfg …...

eNSP网络学习
一、eNSP 1.什么是eNSP eNSP(Enterprise Network Simulation Platform)是一款由华为提供的免费的、可扩展的、图形化操作的网络仿真工具平台,主要对企业网络路由器、交换机进行软件仿真,完美呈现真实设备实景,支持大型网络模拟,让…...

广州xx策划公司MongoDB恢复-2023.09.09
2023.09.08用户的MongoDB数据库被勒索病毒攻击,数据全部被清空。 提示: mongoDB的默认端口为27017,黑客通常通过全网段扫描27017是否开放判断是否是MongoDB服务器。一旦发现27017开放,黑客就会用空密码、弱密码尝试连接数据库。黑…...

golang --- module-aware 模式下 包引入
一、文件列表如下 其中helloWorld目录是main包(package)所在目录,即该目录下所有的goy源文件(不包含子目录)属于main包,hello.go是mian函数所在文件 二、module-aware 模式启用 开启mod模式 go env -w G…...
从原理到实践 | Pytorch tensor 张量花式操作
文章目录 1.张量形状与维度1.1标量(0维张量):1.2 向量(1维张量):1.3矩阵(2维张量):1.4高维张量: 2. 张量其他创建方式2.1 创建全零或全一张量:2.2…...

无涯教程-JavaScript - TRANSPOSE函数
描述 TRANSPOSE函数将单元格的垂直范围作为水平范围返回,反之亦然。必须将TRANSPOSE函数作为数组公式输入,该范围必须具有与行范围和列范围相同的行和列数。 您可以使用TRANSPOSE在工作表上移动数组或范围的垂直和水平方向。 语法 TRANSPOSE (array)键入函数后,按CTRL SHI…...

Webserver项目解析
一.webserver的组成部分 Buffer类 用于存储需要读写的数据 Channel类 存储文件描述符和相应的事件,当发生事件时,调用对应的回调函数 ChannelMap类 Channel数组,用于保存一系列的Channel Dispatcher 监听器,可以设置为epo…...
Spring Cloud 篇
1、什么是SpringCloud ? Spring Cloud 流应用程序启动器是基于 Spring Boot 的 Spring 集成应用程序,提供与外部系统的集成。Spring cloud Task,一个生命周期短暂的微服务框架,用于快速构建执行有限数据处理的应用程序。 2、什么…...

vim,emacs,verilog-mode这几个到底是啥关系?
vim:不多说了被各类coder誉为地表最强最好用的编辑器;gvim,gui vim的意思; emacs:也是一个编辑器,类似vscode; vim在使用的时候为了增强其功能,有好多好多插件,都是以.…...
解决npm run build 打包出现XXXX.js as it exceeds the max of 500KB.
问题描述: npm run build 时出现下面的问题: Note: The code generator has deoptimised the styling of D:\base\node_modules\_element-ui2.15.12element-ui\lib\element-ui.common.js as it exceeds the max of 500KB.在项目的根目录加粗样式下找到 …...
Java 抖音小程序SDK
抖音小程序SDK,抖音SDK 码云地址:dy-open-sdk: 字节跳动,抖音小程序sdk...

Vue.js的服务器端渲染(SSR):为什么和如何
🌷🍁 博主猫头虎(🐅🐾)带您 Go to New World✨🍁 🦄 博客首页——🐅🐾猫头虎的博客🎐 🐳 《面试题大全专栏》 🦕 文章图文…...

Gin 打包vue或react项目输出文件到程序二进制文件
Gin 打包vue或react项目输出文件到程序二进制文件 背景解决方案1. 示例目录结构2. 有如下问题要解决:3. 方案探索 效果 背景 前后端分离已成为行业主流,vue或react等项目生成的文件独立在一个单独目录,与后端项目无关。 实际部署中,通常前面套…...
深度解析shell脚本的命令的原理之pwd
pwd是Print Working Directory的缩写,是一个Unix和Linux shell命令,用于打印当前工作目录的绝对路径。以下是对这个命令的深度解析: 获取当前工作目录:pwd命令通过调用操作系统提供的getcwd(或相应的)系统调…...

Kafka3.0.0版本——消费者(分区的分配以及再平衡)
目录 一、分区的分配以及再平衡1.1、消费者分区及消费者组的概述1.2、如何确定哪个consumer来消费哪个partition的数据1.3、消费者分区分配策略 一、分区的分配以及再平衡 1.1、消费者分区及消费者组的概述 一个consumer group中有多个consumer组成,一个 topic有多…...
Kotlin文件遍历FileTreeWalk filter
Kotlin文件遍历FileTreeWalk filter import java.io.Filefun main(args: Array<String>) {val filePath "."val file File(filePath)val fileTree: FileTreeWalk file.walk()fileTree//.maxDepth(1) //遍历层级1,不检查子目录.filter {it.isFile…...
Activiti兼容达梦数据库
1. 自定义类继承SpringProcessEngineConfiguration类,重写initDatabaseType方法。 package com.ydtf.cbda.module.cbdacim.improcess.config;import org.activiti.engine.ActivitiException; import org.activiti.spring.SpringProcessEngineConfiguration; import…...

shell 流程控制
流程控制 if条件判断 可以使用if来实现多路跳转,条件通常使用test命令 #if语句的语法if condition1then command1elif condition2 then command2else commandNfi 如果then需要和if放在同一行的话,使用;分隔 fi用来结束if语句,相当于…...

多云管理“拦路虎”:深入解析网络互联、身份同步与成本可视化的技术复杂度
一、引言:多云环境的技术复杂性本质 企业采用多云策略已从技术选型升维至生存刚需。当业务系统分散部署在多个云平台时,基础设施的技术债呈现指数级积累。网络连接、身份认证、成本管理这三大核心挑战相互嵌套:跨云网络构建数据…...

51c自动驾驶~合集58
我自己的原文哦~ https://blog.51cto.com/whaosoft/13967107 #CCA-Attention 全局池化局部保留,CCA-Attention为LLM长文本建模带来突破性进展 琶洲实验室、华南理工大学联合推出关键上下文感知注意力机制(CCA-Attention),…...

CentOS下的分布式内存计算Spark环境部署
一、Spark 核心架构与应用场景 1.1 分布式计算引擎的核心优势 Spark 是基于内存的分布式计算框架,相比 MapReduce 具有以下核心优势: 内存计算:数据可常驻内存,迭代计算性能提升 10-100 倍(文档段落:3-79…...
django filter 统计数量 按属性去重
在Django中,如果你想要根据某个属性对查询集进行去重并统计数量,你可以使用values()方法配合annotate()方法来实现。这里有两种常见的方法来完成这个需求: 方法1:使用annotate()和Count 假设你有一个模型Item,并且你想…...
将对透视变换后的图像使用Otsu进行阈值化,来分离黑色和白色像素。这句话中的Otsu是什么意思?
Otsu 是一种自动阈值化方法,用于将图像分割为前景和背景。它通过最小化图像的类内方差或等价地最大化类间方差来选择最佳阈值。这种方法特别适用于图像的二值化处理,能够自动确定一个阈值,将图像中的像素分为黑色和白色两类。 Otsu 方法的原…...
使用van-uploader 的UI组件,结合vue2如何实现图片上传组件的封装
以下是基于 vant-ui(适配 Vue2 版本 )实现截图中照片上传预览、删除功能,并封装成可复用组件的完整代码,包含样式和逻辑实现,可直接在 Vue2 项目中使用: 1. 封装的图片上传组件 ImageUploader.vue <te…...
实现弹窗随键盘上移居中
实现弹窗随键盘上移的核心思路 在Android中,可以通过监听键盘的显示和隐藏事件,动态调整弹窗的位置。关键点在于获取键盘高度,并计算剩余屏幕空间以重新定位弹窗。 // 在Activity或Fragment中设置键盘监听 val rootView findViewById<V…...
python报错No module named ‘tensorflow.keras‘
是由于不同版本的tensorflow下的keras所在的路径不同,结合所安装的tensorflow的目录结构修改from语句即可。 原语句: from tensorflow.keras.layers import Conv1D, MaxPooling1D, LSTM, Dense 修改后: from tensorflow.python.keras.lay…...
#Uniapp篇:chrome调试unapp适配
chrome调试设备----使用Android模拟机开发调试移动端页面 Chrome://inspect/#devices MuMu模拟器Edge浏览器:Android原生APP嵌入的H5页面元素定位 chrome://inspect/#devices uniapp单位适配 根路径下 postcss.config.js 需要装这些插件 “postcss”: “^8.5.…...
NPOI Excel用OLE对象的形式插入文件附件以及插入图片
static void Main(string[] args) {XlsWithObjData();Console.WriteLine("输出完成"); }static void XlsWithObjData() {// 创建工作簿和单元格,只有HSSFWorkbook,XSSFWorkbook不可以HSSFWorkbook workbook new HSSFWorkbook();HSSFSheet sheet (HSSFSheet)workboo…...