当前位置: 首页 > news >正文

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滚动的方向stringtop ,bottom,left,right
isRoller是否可以使用滚轮滚动booleantrue,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 实现一个无缝滚动组件&#xff08;支持鼠标手动滚动&#xff09; 前言 在日常开发中&#xff0c;经常遇到需要支持列表循环滚动展示&#xff0c;特别是在数据化大屏开发中&#xff0c;无缝滚动使用频率更为频繁&#xff0c;在jquery时代&#xff0c;我们常用的无缝滚动组…...

【IP数据报】IP地址和MAC地址的区别

1、用IP地址来标识Internet的主机 在每个IP数据报中&#xff0c;都会携带源IP地址和目标IP地址来标识该IP数据报的源和目的主机。IP数据报在传输过程中&#xff0c;每个中间节点(IP 网关)还需要为其选择从源主机到目的主机的合适的转发路径(即路由)。IP协议可以根据路由选择协…...

高并发笔记

如何设计一个高并发系统&#xff1f;&#xff1a;https://mp.weixin.qq.com/s/yFc-70DEhloWn0G3GDa6Yw 分布式 ID 服务实践&#xff1a;https://mp.weixin.qq.com/s/KAts9Zjj8JpEd0Q6pqLlgQ 一文聊透布隆过滤器&#xff1a;https://mp.weixin.qq.com/s/qJ2fDm1Z57bPSzOBrgiqfg …...

eNSP网络学习

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

广州xx策划公司MongoDB恢复-2023.09.09

2023.09.08用户的MongoDB数据库被勒索病毒攻击&#xff0c;数据全部被清空。 提示&#xff1a; mongoDB的默认端口为27017&#xff0c;黑客通常通过全网段扫描27017是否开放判断是否是MongoDB服务器。一旦发现27017开放&#xff0c;黑客就会用空密码、弱密码尝试连接数据库。黑…...

golang --- module-aware 模式下 包引入

一、文件列表如下 其中helloWorld目录是main包&#xff08;package&#xff09;所在目录&#xff0c;即该目录下所有的goy源文件&#xff08;不包含子目录&#xff09;属于main包&#xff0c;hello.go是mian函数所在文件 二、module-aware 模式启用 开启mod模式 go env -w G…...

从原理到实践 | Pytorch tensor 张量花式操作

文章目录 1.张量形状与维度1.1标量&#xff08;0维张量&#xff09;&#xff1a;1.2 向量&#xff08;1维张量&#xff09;&#xff1a;1.3矩阵&#xff08;2维张量&#xff09;&#xff1a;1.4高维张量&#xff1a; 2. 张量其他创建方式2.1 创建全零或全一张量&#xff1a;2.2…...

无涯教程-JavaScript - TRANSPOSE函数

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

Webserver项目解析

一.webserver的组成部分 Buffer类 用于存储需要读写的数据 Channel类 存储文件描述符和相应的事件&#xff0c;当发生事件时&#xff0c;调用对应的回调函数 ChannelMap类 Channel数组&#xff0c;用于保存一系列的Channel Dispatcher 监听器&#xff0c;可以设置为epo…...

Spring Cloud 篇

1、什么是SpringCloud &#xff1f; Spring Cloud 流应用程序启动器是基于 Spring Boot 的 Spring 集成应用程序&#xff0c;提供与外部系统的集成。Spring cloud Task&#xff0c;一个生命周期短暂的微服务框架&#xff0c;用于快速构建执行有限数据处理的应用程序。 2、什么…...

vim,emacs,verilog-mode这几个到底是啥关系?

vim&#xff1a;不多说了被各类coder誉为地表最强最好用的编辑器&#xff1b;gvim&#xff0c;gui vim的意思&#xff1b; emacs&#xff1a;也是一个编辑器&#xff0c;类似vscode&#xff1b; vim在使用的时候为了增强其功能&#xff0c;有好多好多插件&#xff0c;都是以.…...

解决npm run build 打包出现XXXX.js as it exceeds the max of 500KB.

问题描述&#xff1a; npm run build 时出现下面的问题&#xff1a; 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&#xff0c;抖音SDK 码云地址&#xff1a;dy-open-sdk: 字节跳动&#xff0c;抖音小程序sdk...

Vue.js的服务器端渲染(SSR):为什么和如何

&#x1f337;&#x1f341; 博主猫头虎&#xff08;&#x1f405;&#x1f43e;&#xff09;带您 Go to New World✨&#x1f341; &#x1f984; 博客首页——&#x1f405;&#x1f43e;猫头虎的博客&#x1f390; &#x1f433; 《面试题大全专栏》 &#x1f995; 文章图文…...

Gin 打包vue或react项目输出文件到程序二进制文件

Gin 打包vue或react项目输出文件到程序二进制文件 背景解决方案1. 示例目录结构2. 有如下问题要解决:3. 方案探索 效果 背景 前后端分离已成为行业主流&#xff0c;vue或react等项目生成的文件独立在一个单独目录&#xff0c;与后端项目无关。 实际部署中&#xff0c;通常前面套…...

深度解析shell脚本的命令的原理之pwd

pwd是Print Working Directory的缩写&#xff0c;是一个Unix和Linux shell命令&#xff0c;用于打印当前工作目录的绝对路径。以下是对这个命令的深度解析&#xff1a; 获取当前工作目录&#xff1a;pwd命令通过调用操作系统提供的getcwd&#xff08;或相应的&#xff09;系统调…...

Kafka3.0.0版本——消费者(分区的分配以及再平衡)

目录 一、分区的分配以及再平衡1.1、消费者分区及消费者组的概述1.2、如何确定哪个consumer来消费哪个partition的数据1.3、消费者分区分配策略 一、分区的分配以及再平衡 1.1、消费者分区及消费者组的概述 一个consumer group中有多个consumer组成&#xff0c;一个 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&#xff0c;不检查子目录.filter {it.isFile…...

Activiti兼容达梦数据库

1. 自定义类继承SpringProcessEngineConfiguration类&#xff0c;重写initDatabaseType方法。 package com.ydtf.cbda.module.cbdacim.improcess.config;import org.activiti.engine.ActivitiException; import org.activiti.spring.SpringProcessEngineConfiguration; import…...

shell 流程控制

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

在软件开发中正确使用MySQL日期时间类型的深度解析

在日常软件开发场景中&#xff0c;时间信息的存储是底层且核心的需求。从金融交易的精确记账时间、用户操作的行为日志&#xff0c;到供应链系统的物流节点时间戳&#xff0c;时间数据的准确性直接决定业务逻辑的可靠性。MySQL作为主流关系型数据库&#xff0c;其日期时间类型的…...

k8s从入门到放弃之Ingress七层负载

k8s从入门到放弃之Ingress七层负载 在Kubernetes&#xff08;简称K8s&#xff09;中&#xff0c;Ingress是一个API对象&#xff0c;它允许你定义如何从集群外部访问集群内部的服务。Ingress可以提供负载均衡、SSL终结和基于名称的虚拟主机等功能。通过Ingress&#xff0c;你可…...

【开发技术】.Net使用FFmpeg视频特定帧上绘制内容

目录 一、目的 二、解决方案 2.1 什么是FFmpeg 2.2 FFmpeg主要功能 2.3 使用Xabe.FFmpeg调用FFmpeg功能 2.4 使用 FFmpeg 的 drawbox 滤镜来绘制 ROI 三、总结 一、目的 当前市场上有很多目标检测智能识别的相关算法&#xff0c;当前调用一个医疗行业的AI识别算法后返回…...

DeepSeek 技术赋能无人农场协同作业:用 AI 重构农田管理 “神经网”

目录 一、引言二、DeepSeek 技术大揭秘2.1 核心架构解析2.2 关键技术剖析 三、智能农业无人农场协同作业现状3.1 发展现状概述3.2 协同作业模式介绍 四、DeepSeek 的 “农场奇妙游”4.1 数据处理与分析4.2 作物生长监测与预测4.3 病虫害防治4.4 农机协同作业调度 五、实际案例大…...

让回归模型不再被异常值“带跑偏“,MSE和Cauchy损失函数在噪声数据环境下的实战对比

在机器学习的回归分析中&#xff0c;损失函数的选择对模型性能具有决定性影响。均方误差&#xff08;MSE&#xff09;作为经典的损失函数&#xff0c;在处理干净数据时表现优异&#xff0c;但在面对包含异常值的噪声数据时&#xff0c;其对大误差的二次惩罚机制往往导致模型参数…...

C++.OpenGL (20/64)混合(Blending)

混合(Blending) 透明效果核心原理 #mermaid-svg-SWG0UzVfJms7Sm3e {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-SWG0UzVfJms7Sm3e .error-icon{fill:#552222;}#mermaid-svg-SWG0UzVfJms7Sm3e .error-text{fill…...

DingDing机器人群消息推送

文章目录 1 新建机器人2 API文档说明3 代码编写 1 新建机器人 点击群设置 下滑到群管理的机器人&#xff0c;点击进入 添加机器人 选择自定义Webhook服务 点击添加 设置安全设置&#xff0c;详见说明文档 成功后&#xff0c;记录Webhook 2 API文档说明 点击设置说明 查看自…...

Python 实现 Web 静态服务器(HTTP 协议)

目录 一、在本地启动 HTTP 服务器1. Windows 下安装 node.js1&#xff09;下载安装包2&#xff09;配置环境变量3&#xff09;安装镜像4&#xff09;node.js 的常用命令 2. 安装 http-server 服务3. 使用 http-server 开启服务1&#xff09;使用 http-server2&#xff09;详解 …...

Monorepo架构: Nx Cloud 扩展能力与缓存加速

借助 Nx Cloud 实现项目协同与加速构建 1 &#xff09; 缓存工作原理分析 在了解了本地缓存和远程缓存之后&#xff0c;我们来探究缓存是如何工作的。以计算文件的哈希串为例&#xff0c;若后续运行任务时文件哈希串未变&#xff0c;系统会直接使用对应的输出和制品文件。 2 …...

CppCon 2015 学习:Time Programming Fundamentals

Civil Time 公历时间 特点&#xff1a; 共 6 个字段&#xff1a; Year&#xff08;年&#xff09;Month&#xff08;月&#xff09;Day&#xff08;日&#xff09;Hour&#xff08;小时&#xff09;Minute&#xff08;分钟&#xff09;Second&#xff08;秒&#xff09; 表示…...