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>
const tableRef = ref(null);
nextTick(() => {
  proxy?.$dragTable(tableRef)
})
</script>

实现效果

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

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

 

总结 

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/276517.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

在 iPhone 手机上恢复数据的 7 个有效应用程序

我们的生活离不开 iPhone。无论我们走到哪里&#xff0c;他们都陪伴着我们&#xff0c;让我们保持联系、拍摄照片和视频&#xff0c;并提供娱乐。与此同时&#xff0c;您将计算机安全地放在办公桌上&#xff0c;不受天气影响&#xff0c;也不受伤害。如果您要在任何地方丢失重要…

elementui+vue2 input输入框限制只能输入数字

方法1 自定义表单校验 <el-form :model"Formdata" ref"formRef" :rules"nodeFormRules" label-width"100px"><el-form-itemlabel"年龄"prop"age"><el-input v-model.number"Formdata.age&q…

Spring@Scheduled定时任务与SQLSERVER distinct order by的错误吞噬

目录 Scheduled 提供的调度机制 遇到错误不会抛出 数据库SQL差异 Scheduled 提供的调度机制 cronzonefixedDelayfixedDelayStringfixedRatefixedRateStringinitialDelayinitialDelayString 上面具体怎么用自己代码定位到API上去看注释说明。 遇到错误不会抛出 在SqlSe…

处理HTTP错误响应:Go语言中的稳健之道

开场白&#xff1a;在Web开发中&#xff0c;HTTP错误响应是不可避免的一部分。当请求无法成功完成时&#xff0c;服务器会返回一个错误响应。今天&#xff0c;我们将深入探讨如何在Go语言中优雅地处理这些HTTP错误响应。 知识点一&#xff1a;HTTP错误响应的常见类型HTTP错误响…

开发Python网络爬虫应用,爬取链家新房楼盘信息保存到mongodb中,并分析相关数据

这里写自定义目录标题 爬取代码分析数据问题 爬取代码 import requests import time from lxml import html from pymongo import MongoClient import randomBASEURL https://cq.fang.lianjia.com/loupan/# 获取某市区域的所有链接 def get_areas(url):print(获取区县列表)# …

Python+OpenCV 零基础学习笔记(4-5):计算机图形基础+Python相对文件路径+OpenCV图像+OpenCV视频

文章目录 相关链接运行环境前言计算机图形OpenCV简单使用图形读取文件读取可能会出现的问题&#xff1a;路径不对解决方案其它路径问题解决方案 图像显示保存OpenCV视频视频素材如何获取&#xff1f;简单视频读取 相关链接 【2022B站最好的OpenCV课程推荐】OpenCV从入门到实战 …

JavaSE基础50题:27(数组练习)二分查找

概述 给定一个有序整数数组&#xff0c;实现二分查找。 二分查找的前提&#xff1a;必须是有序的数组&#xff01;&#xff01; 方法具体实现 如找数字5&#xff0c;定义L、R、M&#xff0c;其中M是L和R的中间位置&#xff0c;即(LR) / 2 的位置。 如下图所示&#xff1a; ①…

小米SU7汽车发布会; 齐碳科技C+轮融资;网易 1 月 3 日发布子曰教育大模型;百度文心一言用户数已突破 1 亿

投融资 • 3200 家 VC 投资的创业公司破产&#xff0c;那个投 PLG 的 VC 宣布暂停投资了• 云天励飞参与 AI 技术与解决方案提供商智慧互通 Pre-IPO 轮融资• 百度投资 AIGC 公司必优科技• MicroLED量测公司点莘技术获数千万级融资• 智慧互通获AI上市公司云天励飞Pre-IPO轮战…

Redis布隆过滤器BloomFilter

&#x1f44f;作者简介&#xff1a;大家好&#xff0c;我是爱吃芝士的土豆倪&#xff0c;24届校招生Java选手&#xff0c;很高兴认识大家&#x1f4d5;系列专栏&#xff1a;Spring源码、JUC源码、Kafka原理、分布式技术原理、数据库技术&#x1f525;如果感觉博主的文章还不错的…

【C语言】数据结构——排序(一)

&#x1f497;个人主页&#x1f497; ⭐个人专栏——数据结构学习⭐ &#x1f4ab;点击关注&#x1f929;一起学习C语言&#x1f4af;&#x1f4ab; 目录 导读&#xff1a;数组打印与交换1. 插入排序1.1 直接插入排序1.1.1 基本思想1.1.2 实现代码1.1.3 图解 1.2 希尔排序1.2.1…

Centos7:Jenkins+gitlab+node项目启动(3)

Centos7&#xff1a;Jenkinsgitlabnode项目启动(1) Centos7&#xff1a;Jenkinsgitlabnode项目启动(1)-CSDN博客 Centos7&#xff1a;Jenkinsgitlabnode项目启动(2) Centos7&#xff1a;Jenkinsgitlabnode项目启动(2)-CSDN博客 Centos7&#xff1a;Jenkinsgitlabnode项目启…

python如何读取被压缩的图像

读取压缩的图像数据&#xff1a; PackBits 压缩介绍&#xff1a; CCITT T.3 压缩介绍&#xff1a; 读取压缩的图像数据&#xff1a; 在做图像处理的时候&#xff0c;平时都是使用 函数io.imread() 或者是 函数cv2.imread( ) 函数来读取图像数据&#xff0c;很少用PIL.Image…

华为云CCE-集群内访问-根据ip访问同个pod

华为云CCE-集群内访问-根据ip访问同个pod 问题描述&#xff1a;架构如下&#xff1a;解决方法&#xff1a; 问题描述&#xff1a; 使用service集群内访问时&#xff0c;由于启用了两个pod&#xff0c;导致请求轮询在两个pod之间&#xff0c;无法返回正确的结果。 架构如下&am…

仪表盘、数据分析新增分享功能及应用服务下新增服务实例菜单

近期&#xff0c;博睿数据根据一体化智能可观测平台 Bonree ONE 产品本身&#xff0c;以及用户反馈进行持续的更新和优化。以下为 Bonree ONE 产品功能更新报告第03期内容&#xff0c;更多探索&#xff0c;未完待续。 本次迭代的更新集中在平台的仪表盘、数据分析新增分享功能&…

日志框架简介-Slf4j+Logback入门实践 | 京东云技术团队

前言 随着互联网和大数据的迅猛发展&#xff0c;分布式日志系统和日志分析系统已广泛应用&#xff0c;几乎所有应用程序都使用各种日志框架记录程序运行信息。因此&#xff0c;作为工程师&#xff0c;了解主流的日志记录框架非常重要。虽然应用程序的运行结果不受日志的有无影…

【ubuntu 22.04】安装中文版系统、中文语言包和中文输入法

在系统安装中的键盘布局选择时&#xff0c;选择Chinese - Chinese&#xff0c;此时会自动安装所有的中文语言包和ibus中文输入法系统安装成功重启后&#xff0c;点击设置 - 区域和语言 - 管理已安装的语言 * 根据提示安装更新后&#xff0c;将汉语&#xff08;中国&#xff09;…

springboot整合gateway网关

一、网关基本概念 1、API网关介绍 API 网关出现的原因是微服务架构的出现&#xff0c;不同的微服务一般会有不同的网络地址&#xff0c;而外部客户端可能需要调用多个服务的接口才能完成一个业务需求&#xff0c;如果让客户端直接与各个微服务通信&#xff0c;会有以下的问题…

Python基础语法总结

1.每条语句结束不需要分号(也可以加上), 直接换行, 注意: 如果两行代码写一行, 则必须加分号. 2.定义变量不需要指定类型(如果需要写类型, 需要在变量名后面加": 类型, 这个写法只是方便读代码). 3.变量名大小写敏感. 4.查看变量类型: type(变量名). 5.Python中的int表…

AI-ChatGPTCopilot

ChatGPT chatGPT免费网站列表&#xff1a;GitHub - LiLittleCat/awesome-free-chatgpt: &#x1f193;免费的 ChatGPT 镜像网站列表&#xff0c;持续更新。List of free ChatGPT mirror sites, continuously updated. Copilot 智能生成代码工具 安装步骤 - 登录 github&am…

硬件安全模块 (HSM)、硬件安全引擎 (HSE) 和安全硬件扩展 (SHE)的区别

术语 硬件安全模块 (HSM) &#xff1a;Hardware Security Modules硬件安全引擎 (HSE) &#xff1a;Hardware Security Engines安全硬件扩展 (SHE) &#xff1a; Secure Hardware Extensions 介绍 在汽车行业中&#xff0c;硬件安全模块 (HSM)、硬件安全引擎 (HSE) 和安全硬件…