优化scroll组件
parent
86c8bd3a87
commit
7dbcaecea0
|
@ -1,6 +1,8 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<div class="wrapper"><slot /></div>
|
<div class="wrapper">
|
||||||
|
<div class="content"><slot /></div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="is-horizontal"><span class="thumb"></span></div>
|
<div class="is-horizontal"><span class="thumb"></span></div>
|
||||||
<div class="is-vertical"><span class="thumb"></span></div>
|
<div class="is-vertical"><span class="thumb"></span></div>
|
||||||
|
@ -151,40 +153,42 @@ export default class Scroll {
|
||||||
|
|
||||||
__init__() {
|
__init__() {
|
||||||
/* render */
|
/* render */
|
||||||
this.__BOX__ = this.root.children[1].children[0]
|
|
||||||
|
this.__WRAPPER__ = this.root.children[1].children[0]
|
||||||
|
this.__CONTENT__ = this.__WRAPPER__.firstElementChild
|
||||||
this.__X__ = this.root.children[2].children[0]
|
this.__X__ = this.root.children[2].children[0]
|
||||||
this.__Y__ = this.root.children[3].children[0]
|
this.__Y__ = this.root.children[3].children[0]
|
||||||
this.__last__ = 0
|
this.__last__ = 0
|
||||||
}
|
}
|
||||||
|
|
||||||
get scrollTop() {
|
get scrollTop() {
|
||||||
return this.__BOX__.scrollTop
|
return this.__WRAPPER__.scrollTop
|
||||||
}
|
}
|
||||||
|
|
||||||
set scrollTop(n) {
|
set scrollTop(n) {
|
||||||
n = +n
|
n = +n
|
||||||
if (n === n) {
|
if (n === n) {
|
||||||
this.__BOX__.scrollTop = n
|
this.__WRAPPER__.scrollTop = n
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
get scrollLeft() {
|
get scrollLeft() {
|
||||||
return this.__BOX__.scrollLeft
|
return this.__WRAPPER__.scrollLeft
|
||||||
}
|
}
|
||||||
|
|
||||||
set scrollLeft(n) {
|
set scrollLeft(n) {
|
||||||
n = +n
|
n = +n
|
||||||
if (n === n) {
|
if (n === n) {
|
||||||
this.__BOX__.scrollLeft = n
|
this.__WRAPPER__.scrollLeft = n
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
get scrollHeight() {
|
get scrollHeight() {
|
||||||
return this.__BOX__.scrollHeight
|
return this.__WRAPPER__.scrollHeight
|
||||||
}
|
}
|
||||||
|
|
||||||
get scrollWidth() {
|
get scrollWidth() {
|
||||||
return this.__BOX__.scrollWidth
|
return this.__WRAPPER__.scrollWidth
|
||||||
}
|
}
|
||||||
|
|
||||||
_fetchScrollX(moveX) {
|
_fetchScrollX(moveX) {
|
||||||
|
@ -195,7 +199,7 @@ export default class Scroll {
|
||||||
} else if (moveX > width - xBar) {
|
} else if (moveX > width - xBar) {
|
||||||
moveX = width - xBar
|
moveX = width - xBar
|
||||||
}
|
}
|
||||||
this.__BOX__.scrollLeft = (scrollWidth - width) * (moveX / (width - xBar))
|
this.__WRAPPER__.scrollLeft = (scrollWidth - width) * (moveX / (width - xBar))
|
||||||
this.__X__.style.transform = `translateX(${moveX}px)`
|
this.__X__.style.transform = `translateX(${moveX}px)`
|
||||||
|
|
||||||
return moveX
|
return moveX
|
||||||
|
@ -210,7 +214,7 @@ export default class Scroll {
|
||||||
moveY = height - yBar
|
moveY = height - yBar
|
||||||
}
|
}
|
||||||
|
|
||||||
this.__BOX__.scrollTop = (scrollHeight - height) * (moveY / (height - yBar))
|
this.__WRAPPER__.scrollTop = (scrollHeight - height) * (moveY / (height - yBar))
|
||||||
this.__Y__.style.transform = `translateY(${moveY}px)`
|
this.__Y__.style.transform = `translateY(${moveY}px)`
|
||||||
return moveY
|
return moveY
|
||||||
}
|
}
|
||||||
|
@ -218,7 +222,7 @@ export default class Scroll {
|
||||||
_fireReachEnd(action = 'reach-bottom') {
|
_fireReachEnd(action = 'reach-bottom') {
|
||||||
var { delay } = this.props
|
var { delay } = this.props
|
||||||
var { scrollHeight, height } = this.state
|
var { scrollHeight, height } = this.state
|
||||||
var top = this.__BOX__.scrollTop
|
var top = this.__WRAPPER__.scrollTop
|
||||||
var now = Date.now()
|
var now = Date.now()
|
||||||
|
|
||||||
if (now - this.__last__ > delay) {
|
if (now - this.__last__ > delay) {
|
||||||
|
@ -243,10 +247,10 @@ export default class Scroll {
|
||||||
// 需要减去因为隐藏原生滚动条修正的18像素
|
// 需要减去因为隐藏原生滚动条修正的18像素
|
||||||
let width = this.offsetWidth
|
let width = this.offsetWidth
|
||||||
let height = this.offsetHeight
|
let height = this.offsetHeight
|
||||||
let clientWidth = this.__BOX__.clientWidth
|
let clientWidth = this.__WRAPPER__.clientWidth
|
||||||
let clientHeight = this.__BOX__.clientHeight
|
let clientHeight = this.__WRAPPER__.clientHeight
|
||||||
let scrollWidth = this.__BOX__.scrollWidth
|
let scrollWidth = this.__WRAPPER__.scrollWidth
|
||||||
let scrollHeight = this.__BOX__.scrollHeight
|
let scrollHeight = this.__WRAPPER__.scrollHeight
|
||||||
let yBar = 50 // 滚动条的高度
|
let yBar = 50 // 滚动条的高度
|
||||||
let xBar = 50 // 滚动条的宽度
|
let xBar = 50 // 滚动条的宽度
|
||||||
let { widthFixed, heightFixed } = this.state
|
let { widthFixed, heightFixed } = this.state
|
||||||
|
@ -287,15 +291,15 @@ export default class Scroll {
|
||||||
if (heightFixed > 0) {
|
if (heightFixed > 0) {
|
||||||
style += `height:${heightFixed}px;`
|
style += `height:${heightFixed}px;`
|
||||||
}
|
}
|
||||||
this.__BOX__.style.cssText = style
|
this.__WRAPPER__.style.cssText = style
|
||||||
|
|
||||||
// 需要修正视图容器, 修正完之后, 需要重新获取滚动宽高
|
// 需要修正视图容器, 修正完之后, 需要重新获取滚动宽高
|
||||||
scrollWidth = this.__BOX__.scrollWidth
|
scrollWidth = this.__WRAPPER__.scrollWidth
|
||||||
scrollHeight = this.__BOX__.scrollHeight
|
scrollHeight = this.__WRAPPER__.scrollHeight
|
||||||
}
|
}
|
||||||
// 修正由于未知原因,导致父容器产生滚动距离
|
// 修正由于未知原因,导致父容器产生滚动距离
|
||||||
// 导致的内容被遮挡的bug
|
// 导致的内容被遮挡的bug
|
||||||
this.__BOX__.parentNode.scrollTop = 0
|
this.__WRAPPER__.parentNode.scrollTop = 0
|
||||||
|
|
||||||
yBar = (height * (height / scrollHeight)) >> 0
|
yBar = (height * (height / scrollHeight)) >> 0
|
||||||
xBar = (width * (width / scrollWidth)) >> 0
|
xBar = (width * (width / scrollWidth)) >> 0
|
||||||
|
@ -327,15 +331,15 @@ export default class Scroll {
|
||||||
}
|
}
|
||||||
|
|
||||||
// 鼠标滚动事件
|
// 鼠标滚动事件
|
||||||
this._scrollFn = $.catch(this.__BOX__, 'scroll', ev => {
|
this._scrollFn = $.catch(this.__WRAPPER__, 'scroll', ev => {
|
||||||
// 拖拽时忽略滚动事件
|
// 拖拽时忽略滚动事件
|
||||||
if (this._active) {
|
if (this._active) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
var { axis } = this.props
|
var { axis } = this.props
|
||||||
var { xBar, yBar, thumbX, thumbY, scrollHeight, scrollWidth, width, height } = this.state
|
var { xBar, yBar, thumbX, thumbY, scrollHeight, scrollWidth, width, height } = this.state
|
||||||
var currTop = this.__BOX__.scrollTop
|
var currTop = this.__WRAPPER__.scrollTop
|
||||||
var currLeft = this.__BOX__.scrollLeft
|
var currLeft = this.__WRAPPER__.scrollLeft
|
||||||
|
|
||||||
// x轴 y轴 都为0时, 不作任何处理
|
// x轴 y轴 都为0时, 不作任何处理
|
||||||
if (xBar === 0 && yBar === 0) {
|
if (xBar === 0 && yBar === 0) {
|
||||||
|
@ -424,23 +428,16 @@ export default class Scroll {
|
||||||
$.bind(document, 'mouseup', mouseupFn)
|
$.bind(document, 'mouseup', mouseupFn)
|
||||||
})
|
})
|
||||||
|
|
||||||
// this.__observer1 = new ResizeObserver(this._initFn)
|
this.__observer = new ResizeObserver(this._initFn)
|
||||||
this.__observer2 = new MutationObserver(this._initFn)
|
this.__observer.observe(this.__CONTENT__)
|
||||||
// this.__observer1.observe(this.__BOX__)
|
|
||||||
this.__observer2.observe(this, {
|
|
||||||
childList: true,
|
|
||||||
subtree: true,
|
|
||||||
characterData: true
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
unmounted() {
|
unmounted() {
|
||||||
this.__observer1.disconnect()
|
this.__observer.disconnect()
|
||||||
this.__observer2.disconnect()
|
|
||||||
|
|
||||||
$.unbind(this.__X__, 'mousedown', this._xBarFn)
|
$.unbind(this.__X__, 'mousedown', this._xBarFn)
|
||||||
$.unbind(this.__Y__, 'mousedown', this._yBarFn)
|
$.unbind(this.__Y__, 'mousedown', this._yBarFn)
|
||||||
$.unbind(this.__BOX__, 'scroll', this._scrollFn)
|
$.unbind(this.__WRAPPER__, 'scroll', this._scrollFn)
|
||||||
}
|
}
|
||||||
|
|
||||||
watch() {
|
watch() {
|
||||||
|
|
Reference in New Issue