完成滚动组件的迁移
parent
32f89ab889
commit
ed727a36b8
|
@ -43,7 +43,7 @@
|
||||||
- [ ] `wc-datepicker`日期选择器
|
- [ ] `wc-datepicker`日期选择器
|
||||||
- [ ] `wc-timepicker`时间选择器
|
- [ ] `wc-timepicker`时间选择器
|
||||||
- [x] `wc-code`代码高亮插件
|
- [x] `wc-code`代码高亮插件
|
||||||
- [ ] `wc-scroll`滚动组件
|
- [x] `wc-scroll`滚动组件
|
||||||
- [ ] `wc-silder`滑块组件
|
- [ ] `wc-silder`滑块组件
|
||||||
- [ ] `wc-progress`进度条组件
|
- [ ] `wc-progress`进度条组件
|
||||||
- [ ] `wc-tree`树形菜单组件
|
- [ ] `wc-tree`树形菜单组件
|
||||||
|
|
|
@ -17,6 +17,6 @@
|
||||||
"author": "yutent",
|
"author": "yutent",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@bd/wcui-cli": "^1.1.0"
|
"@bd/wcui-cli": "^1.2.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,22 @@
|
||||||
|
import { nextTick, css, html, Component } from '@bd/core'
|
||||||
|
|
||||||
|
class Dropdown extends Component {
|
||||||
|
mounted() {
|
||||||
|
console.log('Dropdown: ', this.$refs)
|
||||||
|
}
|
||||||
|
|
||||||
|
foo() {}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
return html`
|
||||||
|
<div class="aa" ref="aa" @click=${this.foo}>
|
||||||
|
<div class="bb" ref="bb">
|
||||||
|
<slot ref="dd"></slot>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="cc" ref="cc">${this.foo}</div>
|
||||||
|
`
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Dropdown.reg('dropdown')
|
|
@ -4,258 +4,456 @@
|
||||||
* @date 2023/03/20 15:17:25
|
* @date 2023/03/20 15:17:25
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { css, bind, html, unbind, Component } from '@bd/core'
|
import { css, html, bind, unbind, Component } from '@bd/core'
|
||||||
|
|
||||||
class Scroll extends Component {
|
class Scroll extends Component {
|
||||||
static props = {
|
static props = {
|
||||||
axis: 'xy',
|
axis: 'xy', // 滚动方向, 默认x轴和y轴都可以滚动
|
||||||
distance: 0
|
delay: 1000, // 节流防抖延迟
|
||||||
|
distance: 1 // 触发距离阀值, 单位像素
|
||||||
}
|
}
|
||||||
dragging = false
|
|
||||||
hovering = false
|
|
||||||
static styles = [
|
static styles = [
|
||||||
css`
|
css`
|
||||||
:host {
|
:host {
|
||||||
position: relative;
|
position: relative;
|
||||||
overflow: hidden;
|
|
||||||
display: block;
|
display: block;
|
||||||
}
|
|
||||||
.scroller {
|
|
||||||
position: relative;
|
|
||||||
height: 100%;
|
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
|
||||||
|
.container {
|
||||||
|
overflow: hidden;
|
||||||
|
position: relative;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wrapper {
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
|
scrollbar-width: none;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
scrollbar-width: 0;
|
||||||
|
|
||||||
&::-webkit-scrollbar {
|
&::-webkit-scrollbar {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
scrollbar-width: none; //火狐专属
|
|
||||||
}
|
}
|
||||||
.scroll-bar {
|
.content {
|
||||||
position: absolute;
|
width: fit-content;
|
||||||
background: #909399;
|
height: fit-content;
|
||||||
width: 0;
|
}
|
||||||
height: 0;
|
}
|
||||||
opacity: 0;
|
`,
|
||||||
border-radius: 4px;
|
css`
|
||||||
cursor: pointer;
|
/* 横向 */
|
||||||
transition: opacity ease-in-out 0.2s;
|
|
||||||
|
|
||||||
&.vertical {
|
.is-horizontal,
|
||||||
width: 8px;
|
.is-vertical {
|
||||||
|
visibility: hidden;
|
||||||
|
position: absolute;
|
||||||
|
display: flex;
|
||||||
|
justify-content: flex-end;
|
||||||
|
z-index: 10240;
|
||||||
|
opacity: 0;
|
||||||
|
user-select: none;
|
||||||
|
transition: opacity 0.3s linear, visibility 0.3s linear;
|
||||||
|
|
||||||
|
.thumb {
|
||||||
|
display: block;
|
||||||
|
border-radius: 5px;
|
||||||
|
background: rgba(44, 47, 53, 0.25);
|
||||||
|
cursor: default;
|
||||||
|
transition: width 0.1s linear, height 0.1s linear;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background: rgba(44, 47, 53, 0.5);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.is-horizontal {
|
||||||
|
flex-direction: column;
|
||||||
|
left: 0;
|
||||||
|
bottom: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 10px;
|
||||||
|
|
||||||
|
.thumb {
|
||||||
|
width: 0;
|
||||||
|
height: 6px;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
height: 10px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* 纵向 */
|
||||||
|
.is-vertical {
|
||||||
top: 0;
|
top: 0;
|
||||||
right: 0;
|
right: 0;
|
||||||
}
|
width: 10px;
|
||||||
&.horizon {
|
height: 100%;
|
||||||
height: 8px;
|
|
||||||
bottom: 0;
|
.thumb {
|
||||||
left: 0;
|
width: 6px;
|
||||||
}
|
height: 0;
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
opacity: 0.5 !important;
|
width: 10px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
:host([disabled]) {
|
}
|
||||||
overflow: hidden !important;
|
`,
|
||||||
.scroll-bar {
|
css`
|
||||||
visibility: hidden;
|
:host(:hover) {
|
||||||
|
.is-horizontal,
|
||||||
|
.is-vertical {
|
||||||
|
visibility: visible;
|
||||||
|
opacity: 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
:host([axis='x']) {
|
:host([axis='x']) {
|
||||||
overflow-x: auto;
|
.wrapper {
|
||||||
overflow-y: hidden;
|
overflow-y: hidden;
|
||||||
.vertical {
|
}
|
||||||
|
.is-vertical {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
:host([axis='y']) {
|
:host([axis='y']) {
|
||||||
overflow-y: auto;
|
.wrapper {
|
||||||
overflow-x: hidden;
|
overflow-x: hidden;
|
||||||
.horizon {
|
}
|
||||||
|
.is-horizontal {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
:host([disabled]) {
|
||||||
|
.wrapper {
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
.is-vertical,
|
||||||
|
.is-horizontal {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
`
|
`
|
||||||
]
|
]
|
||||||
|
|
||||||
|
stamp = 0
|
||||||
|
|
||||||
|
cache = {
|
||||||
|
width: 0, // 滚动组件的真实宽度(可视宽高)
|
||||||
|
height: 0, // 滚动组件的真实高度(可视宽高)
|
||||||
|
widthFixed: 0, // 滚动组件的宽度修正值
|
||||||
|
heightFixed: 0, // 滚动组件的高度修正值
|
||||||
|
scrollWidth: 0, // 滚动组件的滚动宽度
|
||||||
|
scrollHeight: 0, // 滚动组件的滚动高度
|
||||||
|
xBar: 0, // 横轴长度
|
||||||
|
yBar: 0, // 纵轴长度
|
||||||
|
thumbX: 0, //横向条滚动距离
|
||||||
|
thumbY: 0 // 纵向条滚动距离
|
||||||
|
}
|
||||||
|
|
||||||
get scrollTop() {
|
get scrollTop() {
|
||||||
return this.$refs.scroller.scrollTop
|
return this.$refs.box?.scrollTop || 0
|
||||||
}
|
}
|
||||||
set scrollTop(val) {
|
|
||||||
this.$refs.scroller.scrollTop = val
|
set scrollTop(n) {
|
||||||
|
n = +n
|
||||||
|
if (n === n) {
|
||||||
|
this.$refs.box.scrollTop = n
|
||||||
}
|
}
|
||||||
get scrollHeight() {
|
|
||||||
return this.$refs.scroller.scrollHeight
|
|
||||||
}
|
|
||||||
set scrollHeight(val) {
|
|
||||||
this.$refs.scroller.scrollHeight = val
|
|
||||||
}
|
}
|
||||||
|
|
||||||
get scrollLeft() {
|
get scrollLeft() {
|
||||||
return this.$refs.scroller.scrollLeft
|
return this.$refs.box?.scrollLeft || 0
|
||||||
}
|
}
|
||||||
set scrollLeft(val) {
|
|
||||||
this.$refs.scroller.scrollLeft = val
|
set scrollLeft(n) {
|
||||||
|
n = +n
|
||||||
|
if (n === n) {
|
||||||
|
this.$refs.box.scrollLeft = n
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
get scrollHeight() {
|
||||||
|
return this.$refs.box?.scrollHeight
|
||||||
|
}
|
||||||
|
|
||||||
get scrollWidth() {
|
get scrollWidth() {
|
||||||
return this.$refs.scroller.scrollWidth
|
return this.$refs.box?.scrollWidth
|
||||||
}
|
|
||||||
set scrollWidth(val) {
|
|
||||||
this.$refs.scroller.scrollWidth = val
|
|
||||||
}
|
|
||||||
render() {
|
|
||||||
return html`
|
|
||||||
<div ref="scroller" class="scroller">
|
|
||||||
<slot ref="slot"></slot>
|
|
||||||
</div>
|
|
||||||
<div ref="vertical" class="scroll-bar vertical"></div>
|
|
||||||
<div ref="horizon" class="scroll-bar horizon"></div>
|
|
||||||
`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
onmouseenter() {
|
__init__(ev) {
|
||||||
this.hovering = true
|
//
|
||||||
this.$refs.vertical.style.opacity = 0.3
|
let width = this.offsetWidth
|
||||||
this.$refs.horizon.style.opacity = 0.3
|
let height = this.offsetHeight
|
||||||
}
|
let scrollWidth = this.scrollWidth
|
||||||
onmouseleave() {
|
let scrollHeight = this.scrollHeight
|
||||||
this.hovering = false
|
let clientWidth = this.$refs.box.clientWidth
|
||||||
if (!this.dragging) {
|
let clientHeight = this.$refs.box.clientHeight
|
||||||
this.$refs.vertical.style.opacity = 0
|
|
||||||
this.$refs.horizon.style.opacity = 0
|
let yBar = 50 // 滚动条的高度
|
||||||
}
|
let xBar = 50 // 滚动条的宽度
|
||||||
}
|
let { widthFixed, heightFixed } = this.cache
|
||||||
onmousedown(e) {
|
let needFixed = false
|
||||||
this.dragging = true
|
let style = ''
|
||||||
const {
|
|
||||||
clientHeight,
|
this.scrollLeft = 0
|
||||||
scrollHeight,
|
this.scrollTop = 0
|
||||||
clientWidth,
|
|
||||||
scrollWidth,
|
// 已经修正过宽度
|
||||||
verticalHeight,
|
if (widthFixed > 0) {
|
||||||
horizonWidth
|
needFixed = scrollHeight === clientHeight
|
||||||
} = this
|
widthFixed = needFixed ? 0 : widthFixed
|
||||||
let start, cur
|
|
||||||
const isVerticalScroll = e.target === this.$refs.vertical
|
|
||||||
if (isVerticalScroll) {
|
|
||||||
start = e.clientY
|
|
||||||
cur = this.scrollTop
|
|
||||||
} else {
|
} else {
|
||||||
start = e.clientX
|
// 高度超出, 说明出现横向滚动条
|
||||||
cur = this.scrollLeft
|
if (scrollHeight > clientHeight) {
|
||||||
|
// width - clientWidth 等于滚动条的宽度, 下同
|
||||||
|
needFixed = true
|
||||||
|
widthFixed = width + (width - clientWidth)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const onmousemove = bind(document, 'mousemove', e => {
|
if (heightFixed > 0) {
|
||||||
let dif, rang, progress
|
needFixed = scrollWidth === clientWidth
|
||||||
if (isVerticalScroll) {
|
heightFixed = needFixed ? 0 : heightFixed
|
||||||
dif = e.clientY - start
|
|
||||||
rang = clientHeight - verticalHeight
|
|
||||||
progress = dif / rang
|
|
||||||
this.scrollTop = cur + progress * (scrollHeight - clientHeight)
|
|
||||||
} else {
|
} else {
|
||||||
dif = e.clientX - start
|
if (scrollWidth > clientWidth) {
|
||||||
rang = clientWidth - horizonWidth
|
needFixed = true
|
||||||
progress = dif / rang
|
heightFixed = height + (height - clientHeight)
|
||||||
this.scrollLeft = cur + progress * (scrollWidth - clientWidth)
|
}
|
||||||
}
|
}
|
||||||
})
|
|
||||||
|
|
||||||
this.onmouseup = bind(document, 'mouseup', () => {
|
this.cache.widthFixed = widthFixed
|
||||||
this.dragging = false
|
this.cache.heightFixed = heightFixed
|
||||||
if (!this.hovering) {
|
|
||||||
this.$refs.vertical.style.opacity = 0
|
if (needFixed) {
|
||||||
this.$refs.horizon.style.opacity = 0
|
if (widthFixed > 0) {
|
||||||
|
style += `width:${widthFixed}px;`
|
||||||
}
|
}
|
||||||
unbind(document, 'mousemove', onmousemove)
|
|
||||||
})
|
if (heightFixed > 0) {
|
||||||
|
style += `height:${heightFixed}px;`
|
||||||
}
|
}
|
||||||
onscroll(ev) {
|
this.$refs.box.style.cssText = style
|
||||||
const {
|
|
||||||
distance,
|
// 需要修正视图容器, 修正完之后, 需要重新获取滚动宽高
|
||||||
scrollTop,
|
scrollWidth = this.$refs.box.scrollWidth
|
||||||
scrollLeft,
|
scrollHeight = this.$refs.box.scrollHeight
|
||||||
clientHeight,
|
}
|
||||||
scrollHeight,
|
// 修正由于未知原因,导致父容器产生滚动距离
|
||||||
clientWidth,
|
// 导致的内容被遮挡的bug
|
||||||
scrollWidth,
|
this.$refs.box.parentNode.scrollTop = 0
|
||||||
verticalHeight,
|
|
||||||
horizonWidth
|
yBar = (height * (height / scrollHeight)) >> 0
|
||||||
} = this
|
xBar = (width * (width / scrollWidth)) >> 0
|
||||||
const { vertical, horizon } = this.$refs
|
|
||||||
const verticalProgress = scrollTop / (scrollHeight - clientHeight) || 0
|
if (yBar < 50) {
|
||||||
const horizonProgress = scrollLeft / (scrollWidth - clientWidth) || 0
|
yBar = 50
|
||||||
vertical.style.transform = `translateY(${
|
}
|
||||||
(clientHeight - verticalHeight) * verticalProgress
|
if (xBar < 50) {
|
||||||
}px)`
|
xBar = 50
|
||||||
horizon.style.transform = `translateX(${
|
}
|
||||||
(clientWidth - horizonWidth) * horizonProgress
|
|
||||||
}px)`
|
// 100%或主体高度比滚动条还短时不显示
|
||||||
if (!ev) {
|
if (xBar >= width) {
|
||||||
//事件对象不存在,则是手动调用的 不触发事件。
|
xBar = 0
|
||||||
|
}
|
||||||
|
if (yBar >= height) {
|
||||||
|
yBar = 0
|
||||||
|
}
|
||||||
|
|
||||||
|
this.cache.height = height
|
||||||
|
this.cache.width = width
|
||||||
|
this.cache.scrollHeight = scrollHeight
|
||||||
|
this.cache.scrollWidth = scrollWidth
|
||||||
|
this.cache.yBar = yBar
|
||||||
|
this.cache.xBar = xBar
|
||||||
|
|
||||||
|
this.$refs.x.style.width = xBar + 'px'
|
||||||
|
this.$refs.y.style.height = yBar + 'px'
|
||||||
|
}
|
||||||
|
|
||||||
|
_fetchScrollX(moveX) {
|
||||||
|
var { scrollWidth, width, xBar } = this.cache
|
||||||
|
|
||||||
|
if (moveX < 0) {
|
||||||
|
moveX = 0
|
||||||
|
} else if (moveX > width - xBar) {
|
||||||
|
moveX = width - xBar
|
||||||
|
}
|
||||||
|
this.scrollLeft = (scrollWidth - width) * (moveX / (width - xBar))
|
||||||
|
this.$refs.x.style.transform = `translateX(${moveX}px)`
|
||||||
|
|
||||||
|
return moveX
|
||||||
|
}
|
||||||
|
|
||||||
|
_fetchScrollY(moveY) {
|
||||||
|
var { scrollHeight, height, yBar } = this.cache
|
||||||
|
|
||||||
|
if (moveY < 0) {
|
||||||
|
moveY = 0
|
||||||
|
} else if (moveY > height - yBar) {
|
||||||
|
moveY = height - yBar
|
||||||
|
}
|
||||||
|
|
||||||
|
this.scrollTop = (scrollHeight - height) * (moveY / (height - yBar))
|
||||||
|
this.$refs.y.style.transform = `translateY(${moveY}px)`
|
||||||
|
return moveY
|
||||||
|
}
|
||||||
|
|
||||||
|
_fireReachEnd(action = 'reach-bottom') {
|
||||||
|
var delay = this.delay
|
||||||
|
var { scrollHeight, height } = this.cache
|
||||||
|
var top = this.$refs.box.scrollTop
|
||||||
|
var now = Date.now()
|
||||||
|
|
||||||
|
if (now - this.stamp > delay) {
|
||||||
|
if (action === 'reach-bottom') {
|
||||||
|
if (height + top < scrollHeight) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if (this.verticalHeight) {
|
|
||||||
if (scrollHeight - scrollTop - clientHeight <= distance) {
|
|
||||||
this.$emit('reach-bottom')
|
|
||||||
}
|
|
||||||
if (scrollTop === 0) {
|
|
||||||
this.$emit('reach-top')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
initScrollBar() {
|
|
||||||
const { axis, clientHeight, scrollHeight, clientWidth, scrollWidth } = this
|
|
||||||
const { vertical, horizon } = this.$refs
|
|
||||||
// console.log(this.$refs)
|
|
||||||
if (clientHeight !== scrollHeight) {
|
|
||||||
this.verticalHeight = (clientHeight / scrollHeight) * clientHeight
|
|
||||||
} else {
|
} else {
|
||||||
this.verticalHeight = 0
|
if (top > 0) {
|
||||||
}
|
return
|
||||||
if (clientWidth !== scrollWidth) {
|
|
||||||
this.horizonWidth = (clientWidth / scrollWidth) * clientWidth
|
|
||||||
} else {
|
|
||||||
this.horizonWidth = 0
|
|
||||||
}
|
|
||||||
if (axis.includes('x')) {
|
|
||||||
horizon.style.width = this.horizonWidth + 'px'
|
|
||||||
bind(horizon, 'mousedown', this.onmousedown.bind(this))
|
|
||||||
}
|
|
||||||
if (axis.includes('y')) {
|
|
||||||
vertical.style.height = this.verticalHeight + 'px'
|
|
||||||
bind(vertical, 'mousedown', this.onmousedown.bind(this))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#watchResize() {
|
|
||||||
const slotList = this.$refs.slot.assignedNodes()
|
this.stamp = now
|
||||||
if (slotList) {
|
this.$emit(action)
|
||||||
slotList.forEach(element => {
|
|
||||||
if (element.nodeType === 1) {
|
|
||||||
this.resizeObserver.observe(element)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mounted() {
|
mounted() {
|
||||||
this.$on('mouseenter', this.onmouseenter)
|
let startX,
|
||||||
this.$on('mouseleave', this.onmouseleave)
|
startY,
|
||||||
this.onscroll = bind(
|
moveX,
|
||||||
this.$refs.scroller,
|
moveY,
|
||||||
'scroll',
|
mousemoveFn = ev => {
|
||||||
this.onscroll.bind(this)
|
let { thumbY, thumbX } = this.cache
|
||||||
)
|
if (startX !== undefined) {
|
||||||
this.resizeObserver = new ResizeObserver(() => {
|
moveX = this._fetchScrollX(thumbX + ev.pageX - startX)
|
||||||
this.initScrollBar()
|
}
|
||||||
this.onscroll()
|
|
||||||
|
if (startY !== undefined) {
|
||||||
|
moveY = this._fetchScrollY(thumbY + ev.pageY - startY)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mouseupFn = ev => {
|
||||||
|
if (Math.abs(ev.pageY - startY) > this.distance) {
|
||||||
|
this._fireReachEnd(ev.pageY > startY ? 'reach-bottom' : 'reach-top')
|
||||||
|
}
|
||||||
|
startX = undefined
|
||||||
|
startY = undefined
|
||||||
|
this.cache.thumbX = moveX || 0
|
||||||
|
this.cache.thumbY = moveY || 0
|
||||||
|
delete this._active
|
||||||
|
unbind(document, 'mousemove', mousemoveFn)
|
||||||
|
unbind(document, 'mouseup', mouseupFn)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 鼠标滚动事件
|
||||||
|
this._scrollFn = bind(this.$refs.box, 'scroll', ev => {
|
||||||
|
ev.stopPropagation()
|
||||||
|
// 拖拽时忽略滚动事件
|
||||||
|
if (this._active) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
var axis = this.axis
|
||||||
|
var {
|
||||||
|
xBar,
|
||||||
|
yBar,
|
||||||
|
thumbX,
|
||||||
|
thumbY,
|
||||||
|
scrollHeight,
|
||||||
|
scrollWidth,
|
||||||
|
width,
|
||||||
|
height
|
||||||
|
} = this.cache
|
||||||
|
var currTop = this.$refs.box.scrollTop
|
||||||
|
var currLeft = this.$refs.box.scrollLeft
|
||||||
|
|
||||||
|
// x轴 y轴 都为0时, 不作任何处理
|
||||||
|
if (xBar === 0 && yBar === 0) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
if (axis === 'y' || axis === 'xy') {
|
||||||
|
if (yBar) {
|
||||||
|
// 修正滚动条的位置
|
||||||
|
// 滚动比例 y 滚动条的可移动距离
|
||||||
|
let fixedY = (currTop / (scrollHeight - height)) * (height - yBar)
|
||||||
|
|
||||||
|
fixedY = fixedY >> 0
|
||||||
|
|
||||||
|
if (fixedY !== thumbY) {
|
||||||
|
this.cache.thumbY = fixedY
|
||||||
|
this.$refs.y.style.transform = `translateY(${fixedY}px)`
|
||||||
|
|
||||||
|
if (Math.abs(fixedY - thumbY) > this.distance) {
|
||||||
|
this._fireReachEnd(fixedY > thumbY ? 'reach-bottom' : 'reach-top')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (axis === 'x' || axis === 'xy') {
|
||||||
|
if (xBar) {
|
||||||
|
// 修正滚动条的位置
|
||||||
|
// 滚动比例 x 滚动条的可移动距离
|
||||||
|
let fixedX = (currLeft / (scrollWidth - width)) * (width - xBar)
|
||||||
|
|
||||||
|
fixedX = fixedX >> 0
|
||||||
|
|
||||||
|
if (fixedX !== thumbX) {
|
||||||
|
this.cache.thumbX = fixedX
|
||||||
|
this.$refs.x.style.transform = `translateX(${fixedX}px)`
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.$emit('scroll')
|
||||||
})
|
})
|
||||||
this.#watchResize()
|
|
||||||
this.$refs.slot.addEventListener('slotchange', () => this.#watchResize())
|
this._yBarFn = bind(this.$refs.y, 'mousedown', ev => {
|
||||||
|
startY = ev.pageY
|
||||||
|
|
||||||
|
this._active = true
|
||||||
|
|
||||||
|
bind(document, 'mousemove', mousemoveFn)
|
||||||
|
bind(document, 'mouseup', mouseupFn)
|
||||||
|
})
|
||||||
|
|
||||||
|
this._xBarFn = bind(this.$refs.x, 'mousedown', ev => {
|
||||||
|
startX = ev.pageX
|
||||||
|
this._active = true
|
||||||
|
|
||||||
|
bind(document, 'mousemove', mousemoveFn)
|
||||||
|
bind(document, 'mouseup', mouseupFn)
|
||||||
|
})
|
||||||
|
|
||||||
|
this.__observer = new ResizeObserver(this.__init__.bind(this))
|
||||||
|
this.__observer.observe(this.$refs.cont)
|
||||||
}
|
}
|
||||||
unmounted() {
|
unmounted() {
|
||||||
this.resizeObserver.disconnect()
|
this.__observer.disconnect()
|
||||||
unbind(document, 'mouseup', this.onmouseup)
|
}
|
||||||
this.$of('mouseenter', this.onmouseenter)
|
|
||||||
this.$of('mouseleave', this.onmouseleave)
|
render() {
|
||||||
this.$of('scroll', this.onscroll)
|
return html`
|
||||||
unbind(this.$refs.vertical, 'mousedown', this.onmousedown)
|
<div class="container">
|
||||||
unbind(this.$refs.horizon, 'mousedown', this.onmousedown)
|
<div class="wrapper" ref="box">
|
||||||
|
<div class="content" ref="cont"><slot></slot></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="is-horizontal"><span ref="x" class="thumb"></span></div>
|
||||||
|
<div class="is-vertical"><span ref="y" class="thumb"></span></div>
|
||||||
|
`
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue