elementui中表格的表头固定 侧边列表固定 滚动条在头部 且使用鼠标滚轮横向时 可同步给顶部滚动条

html

javascript 复制代码
  <!-- 1. 自定义顶部滚动条 -->
    <div 
      class="custom-scrollbar-top" 
      ref="topScrollbar"
      @scroll="handleTopScroll"
    >
      <!-- 内部占位 div,宽度由 JS 动态设置为表格内容的实际宽度 -->
      <div class="scroll-track" :style="{ width: scrollContentWidth + 'px' }"></div>
    </div>
      <!-- 结果表格区域 -->
      <el-table
    :data="tableData"
    style="width: 100%"
    class="industryNewstable"
    ref="myTable"
    max-height="800">
    <el-table-column
      fixed="left"
      prop="date"
      label="日期"
      width="150">
    </el-table-column>
    <el-table-column
      prop="name"
      label="姓名"
      width="120" fixed="left">
    </el-table-column>
    <el-table-column
      prop="province"
      label="省份"
      width="120" fixed="left">
    </el-table-column>
    <el-table-column
      prop="city"
      label="市区"
      width="120">
    </el-table-column>
    <el-table-column
      prop="address"
      label="地址"
      width="300">
    </el-table-column>
    <el-table-column
      prop="zip"
      label="邮编"
      width="120">
    </el-table-column>
  </el-table>

JS

javascript 复制代码
mounted() {
    this.$nextTick(() => {
      this.initScrollbarWidth();
      // 监听窗口变化,防止响应式布局导致宽度计算不准
      window.addEventListener('resize', this.initScrollbarWidth);
    });
  },
  beforeDestroy() {
    // 清理监听器,防止内存泄漏
    const table = this.$refs.myTable;
    if (table && table.$refs.bodyWrapper && this._tableScrollHandler) {
      table.$refs.bodyWrapper.removeEventListener('scroll', this._tableScrollHandler);
    }
    window.removeEventListener('resize', this.initScrollbarWidth);
  },
  methods: {
     // 1. 初始化顶部滚动条的总宽度(必须等于表格内容的实际宽度)
    initScrollbarWidth() {
      const table = this.$refs.myTable;
      if (table && table.$refs.bodyWrapper) {
        // 计算宽度// bodyWrapper.scrollWidth 是内容的真实宽度
        this.scrollContentWidth = table.$refs.bodyWrapper.scrollWidth;

        // 【关键步骤】移除旧的监听器(防止重复绑定),然后添加新的
        const bodyWrapper = table.$refs.bodyWrapper;
        
        // 使用一个绑定的函数引用,方便后续移除(如果需要在 beforeDestroy 移除)
        if (!this._tableScrollHandler) {
          this._tableScrollHandler = this.handleNativeTableScroll.bind(this);
        }
        
        bodyWrapper.removeEventListener('scroll', this._tableScrollHandler);
        bodyWrapper.addEventListener('scroll', this._tableScrollHandler);
      }
    },

    // 2. 当拖动【表格】(或使用鼠标滚轮横向) 时 -> 同步给顶部滚动条
    handleNativeTableScroll(event) {
      // event.target 就是 bodyWrapper
      const scrollLeft = event.target.scrollLeft;
      const topBar = this.$refs.topScrollbar;

      if (topBar) {
        // 只有当顶部滚动条位置和表格不一致时才更新,防止死循环
        // 注意:这里不需要判断 event 是横向还是纵向,scrollLeft 为 0 时赋值也没关系
        if (Math.abs(topBar.scrollLeft - scrollLeft) > 1) {
          topBar.scrollLeft = scrollLeft;
        }
      }
      
      // 如果你还需要处理垂直滚动同步(例如自定义垂直条),可以在这里加
      // const scrollTop = event.target.scrollTop;
    },

    // 当拖动【顶部自定义滚动条】时 -> 同步给表格
    handleTopScroll(event) {
      const table = this.$refs.myTable;
      if (table && table.$refs.bodyWrapper) {
        // 直接设置表格主体的 scrollLeft
        table.$refs.bodyWrapper.scrollLeft = event.target.scrollLeft;
        // 同步表头(防止表头和内容错位)
        if(table.$refs.headerWrapper) {
           table.$refs.headerWrapper.scrollLeft = event.target.scrollLeft;
        }
      }
    },
    }

css

javascript 复制代码
/* 自定义头部滚动条 op */
.table-wrapper {
  position: relative;
  /* 确保容器宽度正常 */
  width: 100%; 
}

/* --- 顶部自定义滚动条样式 --- */
.custom-scrollbar-top {
  width: 100%;
  height: 14px; /* 滚动条高度 */
  overflow-x: auto;
  overflow-y: hidden;
  background-color: #f5f7fa; /* 与表头背景一致 */
  margin-bottom: 0;
  border-bottom: 1px solid #ebeef5; /* 与表头底部分隔线 */
  border-radius: 4px 4px 0 0;
}

/* 内部轨道占位符 */
.scroll-track {
  height: 1px;
  /* width 由 JS 动态绑定 */
}

/* 美化顶部滚动条 (Chrome/Edge/Safari) */
.custom-scrollbar-top::-webkit-scrollbar {
  height: 14px;
}
.custom-scrollbar-top::-webkit-scrollbar-track {
  background: #f5f7fa;
  border-radius: 7px;
}
.custom-scrollbar-top::-webkit-scrollbar-thumb {
  background: #c0c4cc;
  border-radius: 7px;
  border: 3px solid #f5f7fa; /* 增加边距感 */
}
.custom-scrollbar-top::-webkit-scrollbar-thumb:hover {
  background: #909399;
}

/* 美化顶部滚动条 (Firefox) */
.custom-scrollbar-top {
  scrollbar-width: thin;
  scrollbar-color: #c0c4cc #f5f7fa;
}

/* --- 关键:隐藏 Element UI 表格底部的原生滚动条 --- */
::v-deep .industryNewstable .el-table__body-wrapper::-webkit-scrollbar {
  height: 0px !important; /* 强制高度为0 */
  background: transparent;
}
::v-deep .industryNewstable .el-table__body-wrapper::-webkit-scrollbar-track {
  background: transparent;
}
::v-deep .industryNewstable .el-table__body-wrapper::-webkit-scrollbar-thumb {
  background: transparent;
}

/* Firefox 隐藏底部滚动条 */
::v-deep .industryNewstable .el-table__body-wrapper {
  scrollbar-width: none; /* Firefox 64+ */
  -ms-overflow-style: none; /* IE/Edge */
}

/* --- 保持你之前的单元格内容限制样式 --- */
.industryNewstable.el-table /deep/ .cell-scroll-content::-webkit-scrollbar {
  width: 3px;  /* 垂直滚动条宽度 */
}
/* 自定义头部滚动条 end */
.industryNewstable.el-table /deep/ .el-table__fixed{
  bottom:0px !important;
  background-color:#fff;
}
相关推荐
NiceCloud喜云2 小时前
Opus 4.8 的 Effort Control 怎么选:Low 到 Max 五档策略
android·java·大数据·前端·c++·python·spring
wordbaby2 小时前
React Native + RNOH:跨页面数据回传的最佳实践与避坑指南
前端·react native
GISer_Jing2 小时前
Three.js着色器编译机制深度解析
javascript·webgl·着色器
丷丩2 小时前
MapLibre GL JS第22课:查看本地GeoJSON
前端·javascript·map·mapbox·maplibre gl js
油炸自行车2 小时前
Claude Code 错误:API Error: 400 Failed to deserialize the JSON body into the
开发语言·javascript·json·trae·claude code·api error 400
Front思3 小时前
AI前端工程师需要具备能力+
前端·人工智能·ai
ZC跨境爬虫5 小时前
跟着 MDN 学CSS day_29:(掌握文本与字体样式的核心艺术)
前端·css·ui·html·tensorflow
李子琪。6 小时前
网络空间安全深度实战:CSRF 漏洞原理剖析与基于 Token 的纵深防御体系构建(全栈实验报告)
前端·安全·csrf
冰暮流星6 小时前
javascript之history对象介绍
前端·笔记
IT_陈寒6 小时前
Vite热更新失灵?你可能漏了这个配置
前端·人工智能·后端