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

element el-table实现可进行横向拖拽滚动

【问题】表格横向太长,表格横向滚动条位于最底部,需将页面滚动至最底部才可左右拖动表格,用户体验感不好

【需求】基于elment的el-table组件生成的表格,使其可以横向拖拽滚动

【实现】灵感来源于这篇文章【Vue】表格可拖拽滚动,作者已给出原理,感兴趣的可以去了解

 找到el-table元素对应的目标元素(VUE3+Element-Plus)

首先给el-table添加ref,并获取元素

<template><el-table :data="tableData" ref="tableRef"></el-table>
</template>
<script lang="ts" setup>
const tableRef = ref(null);
console.log(tableRef);
</script>

我们要找的是包裹table的第一父元素, .el-scrollbar__wrap类名盒子就是我们要找的目标元素

这里解释一下为什么.el-scrollbar__wrap是父盒子:

我们可以看到.el-scrollbar__view盒子里包裹的是table标签,那么.el-scrollbar__view盒子的宽度就是整个表格的宽度,.el-scrollbar__wrap盒子的宽度又是其父元素的宽度,那么 .el-scrollbar__wrap就是.el-scrollbar__view的父盒子,.el-scrollbar__view子盒子宽度有溢出,.el-scrollbar__wrap父盒子则出现滚动条,使得table可以横向滚动

因此我们要找的目标元素就是 .el-scrollbar__wrap

<template><el-table :data="tableData" ref="tableRef"></el-table>
</template>
<script lang="ts" setup>
const tableRef = ref(null);
//获取目标元素
console.log(tableRef.value.$refs.scrollBarRef.wrapRef);
</script>

​​​​​​​

实现拖拽横向滚动 (通过改变目标元素的scrollLeft值)

需要捕获鼠标事件及拖拽事件并更改目标元素的scrollLeft值则可实现横向滚动

涉及到的事件包括:mousedown,mouseup,mousemove, mouseleave, dragstart,给表格元素添加相应的事件

mousedown

鼠标按下事件,即鼠标按下但未释放的动作

1.可拖拽状态改为允许拖拽。2.记录鼠标位置。3.鼠标样式改为小手。

tableDataRef.value.$el.addEventListener('mousedown', (e: MouseEvent) => {// 拿到目标元素tableBody = tableDataRef.value.$refs.scrollBarRef.wrapRef;// 拖拽状态改为允许拖拽/鼠标样式修改公共方法setMouseFlag(true, tableBody);// 记录鼠标按下位置mouseStart = e.clientX;// 记录元素当前scrollLeft值startX = tableBody.scrollLeft;// 添加 dragstart 事件监听器document.addEventListener('dragstart', handleDragStart);
});

mousemove 

鼠标移动事件,即鼠标在元素内移动的动作

1.判断是否可拖拽。2.允许拖拽时记录鼠标移动距离。3.修改目标元素scrollLeft值。

tableDataRef.value.$el.addEventListener('mousemove', (e: MouseEvent) => {if (mouseFlag) {let offset = e.clientX - mouseStart;(tableBody as HTMLElement).scrollLeft = startX - offset;}
});

mouseup

鼠标释放事件,即鼠标按下后释放的动作

1.可拖拽状态改为禁止拖拽。2.鼠标样式恢复。

tableDataRef.value.$el.addEventListener('mouseup', () => {// console.log('鼠标左键松开++++++++++++');setMouseFlag(false, tableBody);// 移除 dragstart 事件监听器document.removeEventListener('dragstart', handleDragStart);
});

检测到禁止光标手势

监听拖动时,判断是否出现禁止小手标识

如果你选中文字然后点击拖拽时在浏览器中鼠标光标就会变成红色禁止符号

const handleDragStart = (e: DragEvent) => {// console.log('禁止光标手势出现');// 取消默认的拖动效果e.preventDefault();setMouseFlag(false, tableBody);
};

 拖拽状态改为允许拖拽/鼠标样式修改公共方法

const setMouseFlag = (flag: boolean, tableBody?: HTMLElement | null) => {mouseFlag = flag;if (tableBody) {tableBody.style.cursor = flag ? 'grab' : 'auto';}
};

封装成统一函数dragTable,并将其定义为全局变量

/src/utils/common.ts

//设置el-table可进行鼠标左键按下左右拖动
interface TableDataRef {value: {$el: HTMLElement;$refs: {scrollBarRef: {wrapRef: HTMLElement;};};};
}export const dragTable = (tableDataRef: TableDataRef) => {let mouseFlag = false,mouseStart = 0,startX = 0,tableBody: HTMLElement | null = null;//鼠标按下事件,即鼠标按下但未释放的动作。tableDataRef.value.$el.addEventListener('mousedown', (e: MouseEvent) => {tableBody = tableDataRef.value.$refs.scrollBarRef.wrapRef;setMouseFlag(true, tableBody);// mouseFlag = true;mouseStart = e.clientX;startX = tableBody.scrollLeft;// tableBody.style.cursor = 'grab';// 添加 dragstart 事件监听器document.addEventListener('dragstart', handleDragStart);});//鼠标释放事件,即鼠标按下后释放的动作。tableDataRef.value.$el.addEventListener('mouseup', () => {// console.log('鼠标左键松开++++++++++++');
/*     mouseFlag = false;(tableBody as HTMLElement).style.cursor = 'auto'; */setMouseFlag(false, tableBody);// 移除 dragstart 事件监听器document.removeEventListener('dragstart', handleDragStart);});//鼠标移动事件,即鼠标在元素内移动的动作。tableDataRef.value.$el.addEventListener('mousemove', (e: MouseEvent) => {if (mouseFlag) {let offset = e.clientX - mouseStart;(tableBody as HTMLElement).scrollLeft = startX - offset;}});//鼠标离开事件,即鼠标移动到元素外触发这个事件。tableDataRef.value.$el.addEventListener('mouseleave', (e: MouseEvent) => {handleDragStart((e as any))});// 检测到禁止光标手势const handleDragStart = (e: DragEvent) => {// console.log('禁止光标手势出现');// 取消默认的拖动效果e.preventDefault();setMouseFlag(false, tableBody);};const setMouseFlag = (flag: boolean, tableBody?: HTMLElement | null) => {mouseFlag = flag;if (tableBody) {tableBody.style.cursor = flag ? 'grab' : 'auto';}};
};

 main.ts

import { dragTable } from '@/utils/common';
const app = createApp(App);
// 全局方法挂载
app.config.globalProperties.$dragTable = dragTable;

使用全局变量

<template><el-table :data="tableData" ref="tableRef"></el-table>
</template>
<script lang="ts" setup>
import { ComponentInternalInstance, ref } from 'vue';
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
const tableRef = ref(null);
nextTick(() => {proxy?.$dragTable(tableRef)
})
</script>

补充(VUE2 + Element)

可参考这篇文章利用 bodyWrapper 实现表格拖动

el-table 中获取 bodyWrapper 的方法

注意:可能存在Element版本差异,建议下面的获取方式都试试

之前获取 bodyWrapper 方法是 

this.$refs.myTable.bodyWrapper

 现在上面这种方法获取不到了,要更改为

this.$refs.myTable.$elTable.bodyWrapper
或
this.$refs.myTable.$refs.table.bodyWrapper
console.log(this.$refs.mytable)

实现效果

我用的的录制gif软件,鼠标没有变成抓取手势,实际是可以的

如果没有选中文字的需求,可以在mousemove监听中的 if 判断里加上 e.preventDefault();这样拖动时就会很流畅,不受到选中文字影响。

总结 

元素可滚动的前提条件是元素的宽度或高度超出给定区域,且开启了滚动条
拖拽需结合mousedown,mousemove,mouseup,mouseleave,dragstart事件实现
竖向滚动同理,修改ScrollTop值即可

相关文章:

element el-table实现可进行横向拖拽滚动

【问题】表格横向太长&#xff0c;表格横向滚动条位于最底部&#xff0c;需将页面滚动至最底部才可左右拖动表格&#xff0c;用户体验感不好 【需求】基于elment的el-table组件生成的表格&#xff0c;使其可以横向拖拽滚动 【实现】灵感来源于这篇文章【Vue】表格可拖拽滚动&am…...

【兔子王赠书第14期】《YOLO目标检测》涵盖众多目标检测框架,附赠源代码和全书彩图!

文章目录 写在前面YOLO目标检测推荐图书本书特色内容简介作者简介 推荐理由粉丝福利写在后面 写在前面 小伙伴们好久不见吖&#xff0c;本期博主给大家推荐一本关于YOLO目标检测的图书&#xff0c;该书侧重目标检测的基础知识&#xff0c;包含丰富的实践内容&#xff0c;是目标…...

WPF 基础入门(样式)

3.1 一般样式 <Grid Margin"10"><TextBlock Text"Style test" Foreground"Red" FontSize"20"/> </Grid> 3.2内嵌样式 直接在控件上定义样式&#xff0c;如下所示&#xff1a; <Grid Margin"10">…...

Java ArrayList在遍历时删除元素

文章目录 1. Arrays.asList()获取到的ArrayList只能遍历&#xff0c;不能增加或删除元素2. java.util.ArrayList.SubList有实现add()、remove()方法3. 遍历集合时对元素重新赋值、对元素中的属性赋值、删除元素、新增元素3.1 普通for循环3.2 增强for循环3.3 forEach循环3.4 str…...

多模态大模型的前世今生

1 引言 前段时间 ChatGPT 进行了一轮重大更新&#xff1a;多模态上线&#xff0c;能说话&#xff0c;会看图&#xff01;微软发了一篇长达 166 页的 GPT-4V 测评论文&#xff0c;一时间又带起了一阵多模态的热议&#xff0c;随后像是 LLaVA-1.5、CogVLM、MiniGPT-5 等研究工作…...

Android studio 花式按键

一、activity_main.xml代码&#xff1a; <?xml version"1.0" encoding"utf-8"?> <androidx.constraintlayout.widget.ConstraintLayout xmlns:android"http://schemas.android.com/apk/res/android"xmlns:app"http://schemas.a…...

使用spring boot实现异常的统一返回

在这个前后端分离的时代&#xff0c;一个 统一的数据格式非常重要。本次我们实现用spring boot实现一下返回给前端数据的统一格式&#xff0c;不再出现服务器500的错误。 新建一个spring boot项目&#xff0c;并导入knife4j的依赖。 写一个controller控制器&#xff0c;用来是…...

2023-12-11 LeetCode每日一题(最小体力消耗路径)

2023-12-11每日一题 一、题目编号 1631. 最小体力消耗路径二、题目链接 点击跳转到题目位置 三、题目描述 你准备参加一场远足活动。给你一个二维 rows x columns 的地图 heights &#xff0c;其中 heights[row][col] 表示格子 (row, col) 的高度。一开始你在最左上角的格…...

PID为1的僵尸进程的产生及清理

父进程PID为1的僵尸进程通常是由init系统&#xff08;在Linux系统中通常是systemd&#xff09;产生的。这种情况通常发生在以下几种情况&#xff1a; 子进程结束&#xff0c;但其父进程没有正确地调用wait()或waitpid()系统调用来获取子进程的退出状态。在这种情况下&#xff0…...

043、循环神经网络

之——RNN基础 杂谈 第一个对于序列模型的网络&#xff0c;RNN。 正文 1.潜变量自回归模型 潜变量总结过去的信息&#xff0c;再和当前信息一起结合出新的信息。 2.RNN 循环神经网络将观察作为x&#xff0c;与前层隐变量结合得到输出 其中Whh蕴含了整个模型的时序信息&#xf…...

node使用nodemonjs自动启动项目

安装 npm install -g nodemon使用方法 我这里用的是electron项目为例package.json配置 {"name": "my-electron-app","version": "1.0.0","description": "Hello World!","main": "main.js"…...

Ts自封装WebSocket心跳重连

WebSocket是一种在单个TCP连接上进行全双工通信的协议&#xff0c;允许客户端和服务器之间进行双向实时通信。 所谓心跳机制&#xff0c;就是在长时间不使用WebSocket连接的情况下&#xff0c;通过服务器与客户端之间按照一定时间间隔进行少量数据的通信来达到确认连接稳定的手…...

【unity学习笔记】捏人+眨眼效果+口型效果

一、vriod捏人 1.在vroidstudio软件中捏人 2.导出模型&#xff08;.vrm) 二、vrid导入unity的插件 1.在Git上搜索、打开univrm。 2.找到release页面找到合适的插件版本。&#xff08;VRM-0.116.0_0f6c&#xff09; 3.将univrm导入到工程中&#xff08;assets&#xff09;。 三…...

动态规划 | 最长公共子序列问题

文章目录 最长公共子序列题目描述问题分析程序代码复杂度分析 最短编辑距离题目描述问题分析程序代码复杂度分析 编辑距离题目描述输入格式输出格式 问题分析程序代码 最长公共子序列 题目描述 原题链接 给定两个字符串 text1 和 text2&#xff0c;返回这两个字符串的最长 公共…...

RuntimeError: The NVIDIA driver on your system is too old.

【报错】使用 AutoDL 复现实验时遇到 RuntimeError: The NVIDIA driver on your system is too old (found version 11070). Please update your GPU driver by downloading and installing a new version from the URL: http://www.nvidia.com/Download/index.aspx Alternativ…...

Java开发过程中的幂等性问题

幂等性问题&#xff1a; 1. 有时我们在填写某些 form表单 时&#xff0c;保存按钮不小心快速点了两次&#xff0c;表中竟然产生了两条重复的数据&#xff0c;只是id不一样。 2. 我们在项目中为了解决 接口超时 问题&#xff0c;通常会引入了 重试机制 。第一次请求接口超时了…...

基于Docker的软件环境部署脚本,持续更新~

使用时CtrlF搜索你想要的环境&#xff0c;如果没有你想要的环境&#xff0c;可以评论留言&#xff0c;会尽力补充。 本文提供的部署脚本默认参数仅适合开发测试&#xff0c;请根据实际情况调节参数。 数据库 MySQL version: 3.9 services:mysql:image: mysql:8.0.35container…...

C#上位机与欧姆龙PLC的通信08----开发自己的通讯库读写数据

1、介绍 前面已经完成了7项工作&#xff1a; C#上位机与欧姆龙PLC的通信01----项目背景-CSDN博客 C#上位机与欧姆龙PLC的通信02----搭建仿真环境-CSDN博客 C#上位机与欧姆龙PLC的通信03----创建项目工程-CSDN博客 C#上位机与欧姆龙PLC的通信04---- 欧姆龙plc的存储区 C#上…...

【Redis技术专区】「原理分析」探讨Redis6.0为何需要启用多线程

探讨Redis 6.0为何需要启用多线程 背景介绍开启多线程多线程的CPU核心配置IO多线程模式单线程处理方式多线程处理方式 为什么要开启多线程&#xff1f;充分利用多核CPU提高网络I/O效率响应现代应用需求 多线程实现启用多线程 最后总结 背景介绍 在Redis 6.0版本中&#xff0c;…...

simulink代码生成(六)——多级中断的配置

假如系统中存在多个中断&#xff0c;需要合理的配置中断的优先级与中断向量表&#xff1b;在代码生成中&#xff0c;要与中断向量表对应&#xff1b;中断相关的知识参照博客&#xff1a; DSP28335学习——中断向量表的初始化_中断向量表什么时候初始化-CSDN博客 F28335中断系…...

TDengine 快速体验(Docker 镜像方式)

简介 TDengine 可以通过安装包、Docker 镜像 及云服务快速体验 TDengine 的功能&#xff0c;本节首先介绍如何通过 Docker 快速体验 TDengine&#xff0c;然后介绍如何在 Docker 环境下体验 TDengine 的写入和查询功能。如果你不熟悉 Docker&#xff0c;请使用 安装包的方式快…...

【JavaEE】-- HTTP

1. HTTP是什么&#xff1f; HTTP&#xff08;全称为"超文本传输协议"&#xff09;是一种应用非常广泛的应用层协议&#xff0c;HTTP是基于TCP协议的一种应用层协议。 应用层协议&#xff1a;是计算机网络协议栈中最高层的协议&#xff0c;它定义了运行在不同主机上…...

【项目实战】通过多模态+LangGraph实现PPT生成助手

PPT自动生成系统 基于LangGraph的PPT自动生成系统&#xff0c;可以将Markdown文档自动转换为PPT演示文稿。 功能特点 Markdown解析&#xff1a;自动解析Markdown文档结构PPT模板分析&#xff1a;分析PPT模板的布局和风格智能布局决策&#xff1a;匹配内容与合适的PPT布局自动…...

【2025年】解决Burpsuite抓不到https包的问题

环境&#xff1a;windows11 burpsuite:2025.5 在抓取https网站时&#xff0c;burpsuite抓取不到https数据包&#xff0c;只显示&#xff1a; 解决该问题只需如下三个步骤&#xff1a; 1、浏览器中访问 http://burp 2、下载 CA certificate 证书 3、在设置--隐私与安全--…...

vue3+vite项目中使用.env文件环境变量方法

vue3vite项目中使用.env文件环境变量方法 .env文件作用命名规则常用的配置项示例使用方法注意事项在vite.config.js文件中读取环境变量方法 .env文件作用 .env 文件用于定义环境变量&#xff0c;这些变量可以在项目中通过 import.meta.env 进行访问。Vite 会自动加载这些环境变…...

Python 包管理器 uv 介绍

Python 包管理器 uv 全面介绍 uv 是由 Astral&#xff08;热门工具 Ruff 的开发者&#xff09;推出的下一代高性能 Python 包管理器和构建工具&#xff0c;用 Rust 编写。它旨在解决传统工具&#xff08;如 pip、virtualenv、pip-tools&#xff09;的性能瓶颈&#xff0c;同时…...

JavaScript 数据类型详解

JavaScript 数据类型详解 JavaScript 数据类型分为 原始类型&#xff08;Primitive&#xff09; 和 对象类型&#xff08;Object&#xff09; 两大类&#xff0c;共 8 种&#xff08;ES11&#xff09;&#xff1a; 一、原始类型&#xff08;7种&#xff09; 1. undefined 定…...

实战设计模式之模板方法模式

概述 模板方法模式定义了一个操作中的算法骨架&#xff0c;并将某些步骤延迟到子类中实现。模板方法使得子类可以在不改变算法结构的前提下&#xff0c;重新定义算法中的某些步骤。简单来说&#xff0c;就是在一个方法中定义了要执行的步骤顺序或算法框架&#xff0c;但允许子类…...

快速排序算法改进:随机快排-荷兰国旗划分详解

随机快速排序-荷兰国旗划分算法详解 一、基础知识回顾1.1 快速排序简介1.2 荷兰国旗问题 二、随机快排 - 荷兰国旗划分原理2.1 随机化枢轴选择2.2 荷兰国旗划分过程2.3 结合随机快排与荷兰国旗划分 三、代码实现3.1 Python实现3.2 Java实现3.3 C实现 四、性能分析4.1 时间复杂度…...

「Java基本语法」变量的使用

变量定义 变量是程序中存储数据的容器&#xff0c;用于保存可变的数据值。在Java中&#xff0c;变量必须先声明后使用&#xff0c;声明时需指定变量的数据类型和变量名。 语法 数据类型 变量名 [ 初始值]; 示例&#xff1a;声明与初始化 public class VariableDemo {publi…...