1

前言

脱离element-ui又借鉴element-ui,实现类似el-table的固定列和表头的效果

  • 1-1固定,1-2只支持上下滑动,2-1只支持左右滑动,2-2上下、左右均可滑动
  • 其中下图中1-2和2-1两part的滑动事件应用了el-table的mousewheel

效果

图片描述

实现

布局

<div class="tree_table" v-on="handleBodyScroll, resize: handleBodyScroll }">
    <div class="scroll_table" ref="tableScroll">
      <div class="header" ref="scrollHead" v-mousewheel="handleHeaderMousewheel">
          <ul class="header_row row" :style="{ 'width': ulBoxWidth }">
            <li v-for="(date, index) in dateTitList" :key="'head' + index">
                {{ date.dateText }}
            </li>  
          </ul>
      </div>
      <div class="body" ref="tableContent">
          <ul v-for="(item, index) in list" :key="index" class="row" :style="{ 'width': ulBoxWidth }" @mouseenter="handleMouseEnter(index)" @mouseleave="handleMouseLeave(index)">
            <li v-for="(date, index) in dateTitList" :key="'body' + index" class="border-dash">
               <span>1</span>
            </li>
          </ul>
      </div>
    </div>
    <div class="fixed_table" :class="{'table-fixed-left-scroll': hasLeft}">
      <div class="fixed_header">
          <ul class="header_row row">
             <li>项目</li>
          </ul>
      </div>
      <div class="fixed_cont" ref="fixedBody" v-mousewheel="handleFixedMousewheel">
          <ul v-for="(item, index) in list" :key="'fixed_item' + index" class="row" @mouseenter="handleMouseEnter(index)" @mouseleave="handleMouseLeave(index)">
             <li class="border-dash">{{ item.title }}</li>
          </ul>
      </div>
    </div>
</div>

主要方法

handleBodyScroll(event) {
  this.scrollValue = this.bodyWrapper.scrollLeft
  this.hasLeft = this.scrollValue > 0
  this.$refs.fixedBody.scrollTop = this.bodyWrapper.scrollTop
  this.$refs.scrollHead.scrollLeft = this.scrollValue
},
handleFixedMousewheel(event, data) {
  const bodyWrapper = this.bodyWrapper
  if (Math.abs(data.spinY) > 0) {
    const currentScrollTop = this.bodyWrapper.scrollTop
    if (data.pixelY < 0 && currentScrollTop !== 0) {
      event.preventDefault()
    }
    if (data.pixelY > 0 && bodyWrapper.scrollHeight - bodyWrapper.clientHeight > currentScrollTop) {
      event.preventDefault()
    }
    bodyWrapper.scrollTop += Math.ceil(data.pixelY / 5)
  } else {
    bodyWrapper.scrollLeft += Math.ceil(data.pixelX / 5)
  }
},
handleHeaderMousewheel(event, data) {
  const { pixelX, pixelY } = data;
  if (Math.abs(pixelX) >= Math.abs(pixelY)) {
    event.preventDefault();
    this.bodyWrapper.scrollLeft += data.pixelX / 5;
  }
}

element-ui的mousewheel

import normalizeWheel from 'normalize-wheel'

const isFirefox = typeof navigator !== 'undefined' && navigator.userAgent.toLowerCase().indexOf('firefox') > -1;

const mousewheel = function(element, callback) {
  if (element && element.addEventListener) {
    element.addEventListener(isFirefox ? 'DOMMouseScroll' : 'mousewheel', function(event) {
      const normalized = normalizeWheel(event);
      callback && callback.apply(this, [event, normalized]);
    });
  }
};

export default {
  bind(el, binding) {
    mousewheel(el, binding.value);
  }
};

Zlear
4 声望0 粉丝

« 上一篇
token验证机制