2016-12-23 04:00:01 +00:00
|
|
|
// reference https://github.com/noeldelgado/gemini-scrollbar/blob/master/index.js
|
|
|
|
|
|
|
|
import { addResizeListener, removeResizeListener } from 'element-ui/src/utils/resize-event';
|
2016-12-23 04:47:55 +00:00
|
|
|
import scrollbarWidth from 'element-ui/src/utils/scrollbar-width';
|
2016-12-23 04:00:01 +00:00
|
|
|
import * as util from './util';
|
|
|
|
import Bar from './bar';
|
|
|
|
|
2016-12-30 03:24:55 +00:00
|
|
|
/* istanbul ignore next */
|
2016-12-23 04:00:01 +00:00
|
|
|
export default {
|
|
|
|
name: 'ElScrollbar',
|
|
|
|
|
|
|
|
components: { Bar },
|
|
|
|
|
|
|
|
props: {
|
2016-12-23 04:47:55 +00:00
|
|
|
native: Boolean,
|
2016-12-23 04:00:01 +00:00
|
|
|
wrapStyle: {},
|
|
|
|
wrapClass: {},
|
|
|
|
viewClass: {},
|
|
|
|
viewStyle: {},
|
|
|
|
noresize: Boolean, // 如果 container 尺寸不会发生变化,最好设置它可以优化性能
|
|
|
|
tag: {
|
|
|
|
type: String,
|
|
|
|
default: 'div'
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
|
|
|
data() {
|
|
|
|
return {
|
|
|
|
sizeWidth: '0',
|
|
|
|
sizeHeight: '0',
|
|
|
|
moveX: 0,
|
|
|
|
moveY: 0
|
|
|
|
};
|
|
|
|
},
|
|
|
|
|
|
|
|
computed: {
|
|
|
|
wrap() {
|
|
|
|
return this.$refs.wrap;
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
|
|
|
render(h) {
|
2016-12-23 04:47:55 +00:00
|
|
|
let gutter = scrollbarWidth();
|
2016-12-23 04:00:01 +00:00
|
|
|
let style = this.wrapStyle;
|
|
|
|
|
|
|
|
if (gutter) {
|
|
|
|
const gutterWith = `-${gutter}px`;
|
2017-02-22 07:17:22 +00:00
|
|
|
const gutterStyle = `margin-bottom: ${gutterWith}; margin-right: ${gutterWith};`;
|
2016-12-23 04:00:01 +00:00
|
|
|
|
|
|
|
if (Array.isArray(this.wrapStyle)) {
|
|
|
|
style = util.toObject(this.wrapStyle);
|
|
|
|
style.marginRight = style.marginBottom = gutterWith;
|
|
|
|
} else if (typeof this.wrapStyle === 'string') {
|
2017-02-22 07:17:22 +00:00
|
|
|
style += gutterStyle;
|
|
|
|
} else {
|
|
|
|
style = gutterStyle;
|
2016-12-23 04:00:01 +00:00
|
|
|
}
|
|
|
|
}
|
2016-12-23 04:47:55 +00:00
|
|
|
const view = h(this.tag, {
|
|
|
|
class: ['el-scrollbar__view', this.viewClass],
|
|
|
|
style: this.viewStyle,
|
|
|
|
ref: 'resize'
|
|
|
|
}, this.$slots.default);
|
2016-12-23 04:00:01 +00:00
|
|
|
const wrap = (
|
|
|
|
<div
|
|
|
|
ref="wrap"
|
|
|
|
style={ style }
|
|
|
|
onScroll={ this.handleScroll }
|
2017-02-22 07:17:22 +00:00
|
|
|
class={ [this.wrapClass, 'el-scrollbar__wrap', gutter ? '' : 'el-scrollbar__wrap--hidden-default'] }>
|
2016-12-23 04:47:55 +00:00
|
|
|
{ [view] }
|
2016-12-23 04:00:01 +00:00
|
|
|
</div>
|
|
|
|
);
|
2016-12-23 04:47:55 +00:00
|
|
|
let nodes;
|
|
|
|
|
|
|
|
if (!this.native) {
|
|
|
|
nodes = ([
|
|
|
|
wrap,
|
|
|
|
<Bar
|
|
|
|
move={ this.moveX }
|
|
|
|
size={ this.sizeWidth }></Bar>,
|
|
|
|
<Bar
|
|
|
|
vertical
|
|
|
|
move={ this.moveY }
|
|
|
|
size={ this.sizeHeight }></Bar>
|
|
|
|
]);
|
|
|
|
} else {
|
|
|
|
nodes = ([
|
|
|
|
<div
|
|
|
|
ref="wrap"
|
|
|
|
class={ [this.wrapClass, 'el-scrollbar__wrap'] }
|
|
|
|
style={ style }>
|
|
|
|
{ [view] }
|
|
|
|
</div>
|
|
|
|
]);
|
|
|
|
}
|
2016-12-23 04:00:01 +00:00
|
|
|
return h('div', { class: 'el-scrollbar' }, nodes);
|
|
|
|
},
|
|
|
|
|
|
|
|
methods: {
|
|
|
|
handleScroll() {
|
|
|
|
const wrap = this.wrap;
|
|
|
|
|
|
|
|
this.moveY = ((wrap.scrollTop * 100) / wrap.clientHeight);
|
|
|
|
this.moveX = ((wrap.scrollLeft * 100) / wrap.clientWidth);
|
|
|
|
},
|
|
|
|
|
|
|
|
update() {
|
|
|
|
let heightPercentage, widthPercentage;
|
|
|
|
const wrap = this.wrap;
|
2017-02-04 08:15:24 +00:00
|
|
|
if (!wrap) return;
|
2016-12-23 04:00:01 +00:00
|
|
|
|
|
|
|
heightPercentage = (wrap.clientHeight * 100 / wrap.scrollHeight);
|
|
|
|
widthPercentage = (wrap.clientWidth * 100 / wrap.scrollWidth);
|
|
|
|
|
|
|
|
this.sizeHeight = (heightPercentage < 100) ? (heightPercentage + '%') : '';
|
|
|
|
this.sizeWidth = (widthPercentage < 100) ? (widthPercentage + '%') : '';
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
|
|
|
mounted() {
|
2016-12-23 04:47:55 +00:00
|
|
|
if (this.native) return;
|
2016-12-23 04:00:01 +00:00
|
|
|
this.$nextTick(this.update);
|
|
|
|
!this.noresize && addResizeListener(this.$refs.resize, this.update);
|
|
|
|
},
|
|
|
|
|
|
|
|
destroyed() {
|
2016-12-23 04:47:55 +00:00
|
|
|
if (this.native) return;
|
2016-12-23 04:00:01 +00:00
|
|
|
!this.noresize && removeResizeListener(this.$refs.resize, this.update);
|
|
|
|
}
|
|
|
|
};
|