首页 > 其他分享 >转 | element-ui组件table去除下方滚动条,实现鼠标左右拖拽移动表格

转 | element-ui组件table去除下方滚动条,实现鼠标左右拖拽移动表格

时间:2024-07-18 10:33:25浏览次数:12  
标签:const tableBodyWrapper scrollLeft element 滚动条 ui addEventListener table isDown

看起来是vue的语法,我在vue3下面初步试了,还没成功

url  https://mp.weixin.qq.com/s/5_EQjUGMrom7Da-T-gzlKQ

 

 

element-ui组件table去除下方滚动条,实现鼠标左右拖拽移动表格

原创 wsh华仔 懒人wang 2024年07月11日 17:44 山东

时隔多日,再次遇到值得记录的问题。

需求

项目前端使用vue框架,页面使用element-ui进行页面快速搭建。默认的table组件当表格过长时,下方会出现横向的滚动条,便于用户对表格进行左右滑动。考虑到页面美观问题,滚动条设置的很窄,导致用户使用时不方便进行左右滑动。 现要求,去除表格下方滚动条,用户可直接拖拽表格实现左右滑动功能。 表格设置固定表头和列,实践证明并不影响此功能。

思路

鼠标点击进行拖拽,首先想到鼠标的点击事件,添加mousedownmouseleavemouseupmousemove事件的监听器,实现拖拽效果。通过设置tableBodyWrapper.style.overflow = 'hidden';隐藏原生的滚动条。

实现

要实现拖拽功能,并确保 tableBodyWrapper 可以正确拖拽,需要设置事件监听器和对样式进行一些调整。下面是实现代码:

 <template>
    <div ref="tableContainer" class="table-container">
        <el-table
          :data="tableData"
          style="width: 100%">
          <el-table-column
            prop="date"
            label="日期"
            width="180">
          </el-table-column>
          <el-table-column
            prop="name"
            label="姓名"
            width="180">
          </el-table-column>
          <el-table-column
            prop="address"
            label="地址">
          </el-table-column>
        </el-table>
      </div>
  </template>

<script>
export default {
  data() {
    return {
      tableData: [{
            date: '2016-05-02',
            name: '王小虎',
            address: '上海市普陀区金沙江路 1518 弄'
          }, {
            date: '2016-05-04',
            name: '王小虎',
            address: '上海市普陀区金沙江路 1517 弄'
          }, {
            date: '2016-05-01',
            name: '王小虎',
            address: '上海市普陀区金沙江路 1519 弄'
          }, {
            date: '2016-05-03',
            name: '王小虎',
            address: '上海市普陀区金沙江路 1516 弄'
          }]
    };
  },
  mounted() {
    this.enableDrag();
  },
  methods: {
    enableDrag() {
      this.$nextTick(() => {
        const tableContainer = this.$refs.tableContainer;
        const tableBodyWrapper = this.$refs.table.$el.querySelector('.el-table__body-wrapper');
        
        if (!tableBodyWrapper) {
          console.error('找不到表体。');
          return;
        }

        let isDown = false;
        let startX, scrollLeft;

        tableBodyWrapper.addEventListener('mousedown', (e) => {
          isDown = true;
          startX = e.pageX - tableBodyWrapper.offsetLeft;
          scrollLeft = tableBodyWrapper.scrollLeft;
          tableBodyWrapper.style.cursor = 'grabbing';
        });

        tableBodyWrapper.addEventListener('mouseleave', () => {
          isDown = false;
          tableBodyWrapper.style.cursor = 'grab';
        });

        tableBodyWrapper.addEventListener('mouseup', () => {
          isDown = false;
          tableBodyWrapper.style.cursor = 'grab';
        });

        tableBodyWrapper.addEventListener('mousemove', (e) => {
          if (!isDown) return;
          e.preventDefault();
          const x = e.pageX - tableBodyWrapper.offsetLeft;
          const walk = (x - startX) * 2; // scroll-fast
          tableBodyWrapper.scrollLeft = scrollLeft - walk;
        });

        // 隐藏滚动条
        tableBodyWrapper.style.overflowX = 'hidden';
      });
    }
  }
};
</script>

<style>
.table-container {
  overflow: hidden;
  white-space: nowrap;
}

.el-table__body-wrapper {
  cursor: grab;
}

.el-table__body-wrapper:active {
  cursor: grabbing;
}
</style>

 

 

  <template>	<div ref="tableContainer" class="table-container">	    <el-table	      :data="tableData"	      style="width: 100%">	      <el-table-column	        prop="date"	        label="日期"	        width="180">	      </el-table-column>	      <el-table-column	        prop="name"	        label="姓名"	        width="180">	      </el-table-column>	      <el-table-column	        prop="address"	        label="地址">	      </el-table-column>	    </el-table>  	</div>  </template>
<script>export default { data() { return { tableData: [{ date: '2016-05-02', name: '王小虎', address: '上海市普陀区金沙江路 1518 弄' }, { date: '2016-05-04', name: '王小虎', address: '上海市普陀区金沙江路 1517 弄' }, { date: '2016-05-01', name: '王小虎', address: '上海市普陀区金沙江路 1519 弄' }, { date: '2016-05-03', name: '王小虎', address: '上海市普陀区金沙江路 1516 弄' }] }; }, mounted() { this.enableDrag(); }, methods: { enableDrag() { this.$nextTick(() => { const tableContainer = this.$refs.tableContainer; const tableBodyWrapper = this.$refs.table.$el.querySelector('.el-table__body-wrapper'); if (!tableBodyWrapper) { console.error('找不到表体。'); return; }
let isDown = false; let startX, scrollLeft;
tableBodyWrapper.addEventListener('mousedown', (e) => { isDown = true; startX = e.pageX - tableBodyWrapper.offsetLeft; scrollLeft = tableBodyWrapper.scrollLeft; tableBodyWrapper.style.cursor = 'grabbing'; });
tableBodyWrapper.addEventListener('mouseleave', () => { isDown = false; tableBodyWrapper.style.cursor = 'grab'; });
tableBodyWrapper.addEventListener('mouseup', () => { isDown = false; tableBodyWrapper.style.cursor = 'grab'; });
tableBodyWrapper.addEventListener('mousemove', (e) => { if (!isDown) return; e.preventDefault(); const x = e.pageX - tableBodyWrapper.offsetLeft; const walk = (x - startX) * 2; // scroll-fast tableBodyWrapper.scrollLeft = scrollLeft - walk; });
// 隐藏滚动条 tableBodyWrapper.style.overflowX = 'hidden'; }); } }};</script>
<style>.table-container { overflow: hidden; white-space: nowrap;}
.el-table__body-wrapper { cursor: grab;}
.el-table__body-wrapper:active { cursor: grabbing;}</style>

解释:

  • 获取DOM元素:在this.$nextTick()回调中,通过this.$refs.table.$el.querySelector('.el-table__body-wrapper')获取到实际的表格内容区域的DOM元素。这样就确保我们在对DOM元素进行操作,而不是组件实例。
  • 检查 DOM 元素存在:在 this.$nextTick 中,我们先检查 tableElement 是否存在,然后再查询 tableBodyWrapper
  • 添加错误处理:如果 tableBodyWrapper 没有找到,输出错误信息到控制台。这有助于调试并确保代码的稳健性。
  • 拖拽事件绑定到 tableBodyWrapper:确保拖拽事件绑定在实际可滚动的 tableBodyWrapper 上。
  • 样式调整:使用 tableBodyWrapper 的样式来显示抓手光标,并在拖动时切换光标样式。
  • 隐藏水平滚动条:通过设置 overflowX: hidden 来隐藏原生滚动条,但确保滚动功能仍然有效。

更新兼容手机拖拽功能

 

<div ref="tableContainer" class="table-container">
  <el-table ref="table">
  </el-table>
</div>

methods: {
  enableDrag () {
    this.$nextTick(() => {
      const tableContainer = this.$refs.tableContainer;
      const tableBodyWrapper = this.$refs.table.$el.querySelector('.el-table__body-wrapper');

      if (!tableBodyWrapper) {
        console.error('Table body wrapper not found.');
        return;
      }

      let isDown = false;
      let startX, scrollLeft;

      // 鼠标事件
      tableBodyWrapper.addEventListener('mousedown', (e) => {
        isDown = true;
        startX = e.pageX - tableBodyWrapper.offsetLeft;
        scrollLeft = tableBodyWrapper.scrollLeft;
        tableBodyWrapper.style.cursor = 'grabbing';
      });

      tableBodyWrapper.addEventListener('mouseleave', () => {
        isDown = false;
        tableBodyWrapper.style.cursor = 'grab';
      });

      tableBodyWrapper.addEventListener('mouseup', () => {
        isDown = false;
        tableBodyWrapper.style.cursor = 'grab';
      });

      tableBodyWrapper.addEventListener('mousemove', (e) => {
        if (!isDown) return;
        e.preventDefault();
        const x = e.pageX - tableBodyWrapper.offsetLeft;
        const walk = (x - startX) * 2; // scroll-fast
        tableBodyWrapper.scrollLeft = scrollLeft - walk;
      });

      // 触摸事件
      tableBodyWrapper.addEventListener('touchstart', (e) => {
        isDown = true;
        startX = e.touches[0].pageX - tableBodyWrapper.offsetLeft;
        scrollLeft = tableBodyWrapper.scrollLeft;
      });

      tableBodyWrapper.addEventListener('touchend', () => {
        isDown = false;
      });

      tableBodyWrapper.addEventListener('touchmove', (e) => {
        if (!isDown) return;
        e.preventDefault();
        const x = e.touches[0].pageX - tableBodyWrapper.offsetLeft;
        const walk = (x - startX) * 2; // scroll-fast
        tableBodyWrapper.scrollLeft = scrollLeft - walk;
      });

      // 隐藏滚动条
      tableBodyWrapper.style.overflowX = 'hidden';
    });
  }
}

 

因之前代码只对pc端进行实现,手机进行拖拽无反应,现新加入手机拖拽事件。以下是修改后的代码,添加了触摸事件的支持:

<div ref="tableContainer" class="table-container">  <el-table ref="table">  </el-table></div>
methods: { enableDrag () { this.$nextTick(() => { const tableContainer = this.$refs.tableContainer; const tableBodyWrapper = this.$refs.table.$el.querySelector('.el-table__body-wrapper');
if (!tableBodyWrapper) { console.error('Table body wrapper not found.'); return; }
let isDown = false; let startX, scrollLeft;
// 鼠标事件 tableBodyWrapper.addEventListener('mousedown', (e) => { isDown = true; startX = e.pageX - tableBodyWrapper.offsetLeft; scrollLeft = tableBodyWrapper.scrollLeft; tableBodyWrapper.style.cursor = 'grabbing'; });
tableBodyWrapper.addEventListener('mouseleave', () => { isDown = false; tableBodyWrapper.style.cursor = 'grab'; });
tableBodyWrapper.addEventListener('mouseup', () => { isDown = false; tableBodyWrapper.style.cursor = 'grab'; });
tableBodyWrapper.addEventListener('mousemove', (e) => { if (!isDown) return; e.preventDefault(); const x = e.pageX - tableBodyWrapper.offsetLeft; const walk = (x - startX) * 2; // scroll-fast tableBodyWrapper.scrollLeft = scrollLeft - walk; });
// 触摸事件 tableBodyWrapper.addEventListener('touchstart', (e) => { isDown = true; startX = e.touches[0].pageX - tableBodyWrapper.offsetLeft; scrollLeft = tableBodyWrapper.scrollLeft; });
tableBodyWrapper.addEventListener('touchend', () => { isDown = false; });
tableBodyWrapper.addEventListener('touchmove', (e) => { if (!isDown) return; e.preventDefault(); const x = e.touches[0].pageX - tableBodyWrapper.offsetLeft; const walk = (x - startX) * 2; // scroll-fast tableBodyWrapper.scrollLeft = scrollLeft - walk; });
// 隐藏滚动条 tableBodyWrapper.style.overflowX = 'hidden'; }); }}

在这个代码中,我们为 touchstarttouchend 和 touchmove 事件添加了相应的处理函数,以支持在手机上的左右拖拽操作。这样既兼容了PC上的鼠标拖拽,也支持了手机上的触摸拖拽。

 

标签:const,tableBodyWrapper,scrollLeft,element,滚动条,ui,addEventListener,table,isDown
From: https://www.cnblogs.com/dhjy123/p/18308915

相关文章

  • vue element ui 简单表格下钻逻辑浅记
    在Vue.js中结合ElementUI来实现点击表格字段跳转到对应字段的表格,并使用面包屑导航以方便用户随时跳回之前的层级,可以通过以下步骤来完成:步骤1:准备数据结构首先,你需要一个嵌套的数据结构来表示不同级别的表格数据。例如:constdata=[{id:1,name:'Pare......
  • 使用ElementUI和element-china-area-data库实现省市区三级联动组件封装
    使用ElementUI和element-china-area-data库实现省市区三级联动组件封装在前端开发中,省市区三级联动是一个常见的需求。今天我们将使用Vue.js和ElementUI组件库,结合element-china-area-data库,来实现一个省市区三级联动的组件。这个组件不仅可以提高用户体验,还能大大简化我们的代码......
  • 界面控件DevExpress Blazor UI v24.1 - 发布全新TreeList组件
    DevExpress BlazorUI组件使用了C#为BlazorServer和BlazorWebAssembly创建高影响力的用户体验,这个UI自建库提供了一套全面的原生BlazorUI组件(包括PivotGrid、调度程序、图表、数据编辑器和报表等)。DevExpress Blazor控件目前已经升级到v24.1版本了,此版本发布了全新的TreeLi......
  • COMP9021 Principles of Programming Coding Quiz 5
     COMP9021PrinciplesofProgrammingTerm2,2024CodingQuiz5Worth4marksanddueWeek8Thursday@9pmDescriptionYouareprovidedwithastubinwhichyouneedtoinsertyourcodewhereindicatedwithoutdoinganychangestotheexistingcode......
  • Java学习日历(String,StringBuilder,Stringjoiner)
     金额转换packageme.JavaStudy;importjava.util.Scanner;//币值转换publicclassCaptial{publicstaticvoidmain(String[]args){Scannersc=newScanner(System.in);System.out.println("请输入一个数字");intnumber=sc.ne......
  • 自研electron31+vue3+elementPlus桌面聊天Exe应用-源码版
    Vue3-ElectronWechat:基于最新前端跨平台技术electron31.x整合高性能构建工具vite.js5搭建的一款高颜值桌面端仿微信界面聊天程序。整个项目采用vue3setup语法糖编码开发,全新封装electron多窗口管理模式。基于vite5+electron31+vue3仿微信客户端聊天【源码版】功能特......
  • 全面Burp Suite教程:深入掌握Web应用安全测试的利器
    目录Burpsuite简介1.1什么是BurpSuite?1.2BurpSuite的主要功能和组件Burpsuite安装与设置2.1下载和安装BurpSuite2.2Burpsuite设置字体2.3Burpsuite中文乱码问题Scanner模块(扫描与漏洞检测)3.1使用Scanner模块进行自动扫描3.1.1新建扫描3.1.2设置扫描范围3.1......
  • 处理 Element Plus 告警
    处理ElementPlus告警在使用ElementPlus的Pagination分页组件时,出现告警:ElementPlusError:[ElPagination]Deprecatedusagesdetected,pleaserefertotheel-paginationdocumentationformoredetails代码大致如下:<template><el-rowstyle="margin-top:15px;"......
  • Ubuntu+Docker+Ollama+WebUI
    Ubuntu备份源文件sudocp/etc/apt/sources.list/etc/apt/sources.list.backup编辑/etc/apt/sources.list#默认注释了源码镜像以提高aptupdate速度,如有需要可自行取消注释debhttps://mirrors.tuna.tsinghua.edu.cn/ubuntu/focalmainrestricteduniversemultivers......
  • SwiftUI Release 引入的辅助焦点管理
    文章目录前言使用@FocusState属性包装器高级技巧:专用辅助技术可聚焦字段的高级用法优化体验运行截图总结前言SwiftUIRelease引入了强大的新功能,其中之一是辅助焦点管理。这个新功能使得在SwiftUI中处理辅助技术(如VoiceOver和SwitchControl)的焦点状态变得......