当前位置: 首页 > 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;相当于…...

ES6从入门到精通:前言

ES6简介 ES6&#xff08;ECMAScript 2015&#xff09;是JavaScript语言的重大更新&#xff0c;引入了许多新特性&#xff0c;包括语法糖、新数据类型、模块化支持等&#xff0c;显著提升了开发效率和代码可维护性。 核心知识点概览 变量声明 let 和 const 取代 var&#xf…...

<6>-MySQL表的增删查改

目录 一&#xff0c;create&#xff08;创建表&#xff09; 二&#xff0c;retrieve&#xff08;查询表&#xff09; 1&#xff0c;select列 2&#xff0c;where条件 三&#xff0c;update&#xff08;更新表&#xff09; 四&#xff0c;delete&#xff08;删除表&#xf…...

聊聊 Pulsar:Producer 源码解析

一、前言 Apache Pulsar 是一个企业级的开源分布式消息传递平台&#xff0c;以其高性能、可扩展性和存储计算分离架构在消息队列和流处理领域独树一帜。在 Pulsar 的核心架构中&#xff0c;Producer&#xff08;生产者&#xff09; 是连接客户端应用与消息队列的第一步。生产者…...

多种风格导航菜单 HTML 实现(附源码)

下面我将为您展示 6 种不同风格的导航菜单实现&#xff0c;每种都包含完整 HTML、CSS 和 JavaScript 代码。 1. 简约水平导航栏 <!DOCTYPE html> <html lang"zh-CN"> <head><meta charset"UTF-8"><meta name"viewport&qu…...

第 86 场周赛:矩阵中的幻方、钥匙和房间、将数组拆分成斐波那契序列、猜猜这个单词

Q1、[中等] 矩阵中的幻方 1、题目描述 3 x 3 的幻方是一个填充有 从 1 到 9 的不同数字的 3 x 3 矩阵&#xff0c;其中每行&#xff0c;每列以及两条对角线上的各数之和都相等。 给定一个由整数组成的row x col 的 grid&#xff0c;其中有多少个 3 3 的 “幻方” 子矩阵&am…...

Element Plus 表单(el-form)中关于正整数输入的校验规则

目录 1 单个正整数输入1.1 模板1.2 校验规则 2 两个正整数输入&#xff08;联动&#xff09;2.1 模板2.2 校验规则2.3 CSS 1 单个正整数输入 1.1 模板 <el-formref"formRef":model"formData":rules"formRules"label-width"150px"…...

力扣-35.搜索插入位置

题目描述 给定一个排序数组和一个目标值&#xff0c;在数组中找到目标值&#xff0c;并返回其索引。如果目标值不存在于数组中&#xff0c;返回它将会被按顺序插入的位置。 请必须使用时间复杂度为 O(log n) 的算法。 class Solution {public int searchInsert(int[] nums, …...

rnn判断string中第一次出现a的下标

# coding:utf8 import torch import torch.nn as nn import numpy as np import random import json""" 基于pytorch的网络编写 实现一个RNN网络完成多分类任务 判断字符 a 第一次出现在字符串中的位置 """class TorchModel(nn.Module):def __in…...

九天毕昇深度学习平台 | 如何安装库?

pip install 库名 -i https://pypi.tuna.tsinghua.edu.cn/simple --user 举个例子&#xff1a; 报错 ModuleNotFoundError: No module named torch 那么我需要安装 torch pip install torch -i https://pypi.tuna.tsinghua.edu.cn/simple --user pip install 库名&#x…...

论文笔记——相干体技术在裂缝预测中的应用研究

目录 相关地震知识补充地震数据的认识地震几何属性 相干体算法定义基本原理第一代相干体技术&#xff1a;基于互相关的相干体技术&#xff08;Correlation&#xff09;第二代相干体技术&#xff1a;基于相似的相干体技术&#xff08;Semblance&#xff09;基于多道相似的相干体…...