前言
脱离 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);
}
};