mirror of
https://github.com/tusen-ai/naive-ui.git
synced 2024-12-21 04:50:14 +08:00
feat(scrollbar): support custom container & content
This commit is contained in:
parent
c04c51cffd
commit
3579187872
@ -13,6 +13,7 @@
|
|||||||
@dragstart.capture="handleDragStart"
|
@dragstart.capture="handleDragStart"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
|
v-if="!container"
|
||||||
ref="scrollContainer"
|
ref="scrollContainer"
|
||||||
class="n-scrollbar-container"
|
class="n-scrollbar-container"
|
||||||
@scroll="handleScroll"
|
@scroll="handleScroll"
|
||||||
@ -24,6 +25,9 @@
|
|||||||
<slot />
|
<slot />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<template v-else>
|
||||||
|
<slot />
|
||||||
|
</template>
|
||||||
<div
|
<div
|
||||||
ref="verticalRail"
|
ref="verticalRail"
|
||||||
class="n-scrollbar-rail n-scrollbar-rail--vertical"
|
class="n-scrollbar-rail n-scrollbar-rail--vertical"
|
||||||
@ -89,6 +93,14 @@ export default {
|
|||||||
withoutScrollbar: {
|
withoutScrollbar: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: false
|
default: false
|
||||||
|
},
|
||||||
|
container: {
|
||||||
|
type: Function,
|
||||||
|
default: null
|
||||||
|
},
|
||||||
|
content: {
|
||||||
|
type: Function,
|
||||||
|
default: null
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
data () {
|
data () {
|
||||||
@ -179,7 +191,7 @@ export default {
|
|||||||
// console.log('[NScrollbar.updated]')
|
// console.log('[NScrollbar.updated]')
|
||||||
},
|
},
|
||||||
beforeDestroy () {
|
beforeDestroy () {
|
||||||
resizeObserverDelagate.unregisterHandler(this.$refs.scrollContent)
|
resizeObserverDelagate.unregisterHandler(this._content())
|
||||||
},
|
},
|
||||||
destroyed () {
|
destroyed () {
|
||||||
window.clearTimeout(this.horizontalScrollbarVanishTimerId)
|
window.clearTimeout(this.horizontalScrollbarVanishTimerId)
|
||||||
@ -189,9 +201,27 @@ export default {
|
|||||||
},
|
},
|
||||||
mounted () {
|
mounted () {
|
||||||
this.updateParameters()
|
this.updateParameters()
|
||||||
resizeObserverDelagate.registerHandler(this.$refs.scrollContent, this.updateParameters)
|
this.$nextTick().then(() => {
|
||||||
|
if (this.container) {
|
||||||
|
const containerEl = this.container()
|
||||||
|
containerEl.addEventListener('scroll', this.handleScroll)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
resizeObserverDelagate.registerHandler(this._content(), this.updateParameters)
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
_container () {
|
||||||
|
if (this.container) {
|
||||||
|
return this.container()
|
||||||
|
}
|
||||||
|
return this.$refs.scrollContainer
|
||||||
|
},
|
||||||
|
_content () {
|
||||||
|
if (this.content) {
|
||||||
|
return this.content()
|
||||||
|
}
|
||||||
|
return this.$refs.scrollContent
|
||||||
|
},
|
||||||
disableScrollbar () {
|
disableScrollbar () {
|
||||||
this.hideScrollbar()
|
this.hideScrollbar()
|
||||||
this.disabled = true
|
this.disabled = true
|
||||||
@ -206,30 +236,30 @@ export default {
|
|||||||
this.showVeriticalScrollbar = true
|
this.showVeriticalScrollbar = true
|
||||||
},
|
},
|
||||||
scrollToTop (smooth = false) {
|
scrollToTop (smooth = false) {
|
||||||
if (this.$refs.scrollContainer) {
|
if (this._container()) {
|
||||||
this.$refs.scrollContainer.scrollTo({
|
this._container().scrollTo({
|
||||||
top: 0
|
top: 0
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
scrollToBottom (smooth = false) {
|
scrollToBottom (smooth = false) {
|
||||||
if (this.$refs.scrollContainer) {
|
if (this._container()) {
|
||||||
this.$refs.scrollContainer.scrollTo({
|
this._container().scrollTo({
|
||||||
top: this.$refs.scrollContent.offsetHeight
|
top: this._content().offsetHeight
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
scrollToElement (el) {
|
scrollToElement (el) {
|
||||||
if (this.withoutScrollbar) return
|
if (this.withoutScrollbar) return
|
||||||
if (el.offsetTop < this.$refs.scrollContainer.scrollTop) {
|
if (el.offsetTop < this._container().scrollTop) {
|
||||||
this.$refs.scrollContainer.scrollTo({
|
this._container().scrollTo({
|
||||||
top: el.offsetTop,
|
top: el.offsetTop,
|
||||||
left: 0,
|
left: 0,
|
||||||
behavior: 'smooth'
|
behavior: 'smooth'
|
||||||
})
|
})
|
||||||
} else if (el.offsetTop + el.offsetHeight > this.$refs.scrollContainer.scrollTop + this.$refs.scrollContainer.offsetHeight) {
|
} else if (el.offsetTop + el.offsetHeight > this._container().scrollTop + this._container().offsetHeight) {
|
||||||
this.$refs.scrollContainer.scrollTo({
|
this._container().scrollTo({
|
||||||
top: el.offsetTop + el.offsetHeight - this.$refs.scrollContainer.offsetHeight,
|
top: el.offsetTop + el.offsetHeight - this._container().offsetHeight,
|
||||||
left: 0,
|
left: 0,
|
||||||
behavior: 'smooth'
|
behavior: 'smooth'
|
||||||
})
|
})
|
||||||
@ -285,26 +315,26 @@ export default {
|
|||||||
},
|
},
|
||||||
handleScroll (e) {
|
handleScroll (e) {
|
||||||
if (this.disabled) return
|
if (this.disabled) return
|
||||||
this.$emit('scroll', e, this.$refs.scrollContainer, this.$refs.scrollContent)
|
this.$emit('scroll', e, this._container(), this._content())
|
||||||
this.updateScrollParameters()
|
this.updateScrollParameters()
|
||||||
},
|
},
|
||||||
updateScrollParameters () {
|
updateScrollParameters () {
|
||||||
if (this.$refs.scrollContainer) {
|
if (this._container()) {
|
||||||
this.containerScrollTop = this.$refs.scrollContainer.scrollTop
|
this.containerScrollTop = this._container().scrollTop
|
||||||
this.containerScrollLeft = this.$refs.scrollContainer.scrollLeft
|
this.containerScrollLeft = this._container().scrollLeft
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
updatePositionParameters () {
|
updatePositionParameters () {
|
||||||
/**
|
/**
|
||||||
* Don't use getClientBoundingRect because element may be scale transformed
|
* Don't use getClientBoundingRect because element may be scale transformed
|
||||||
*/
|
*/
|
||||||
if (this.$refs.scrollContent) {
|
if (this._content()) {
|
||||||
this.contentHeight = this.$refs.scrollContent.offsetHeight
|
this.contentHeight = this._content().offsetHeight
|
||||||
this.contentWidth = this.$refs.scrollContent.offsetWidth
|
this.contentWidth = this._content().offsetWidth
|
||||||
}
|
}
|
||||||
if (this.$refs.scrollContainer) {
|
if (this._container()) {
|
||||||
this.containerHeight = this.$refs.scrollContainer.offsetHeight
|
this.containerHeight = this._container().offsetHeight
|
||||||
this.containerWidth = this.$refs.scrollContainer.offsetWidth
|
this.containerWidth = this._container().offsetWidth
|
||||||
}
|
}
|
||||||
if (this.$refs.horizontalRail) {
|
if (this.$refs.horizontalRail) {
|
||||||
this.horizontalRailWidth = this.$refs.horizontalRail.offsetWidth
|
this.horizontalRailWidth = this.$refs.horizontalRail.offsetWidth
|
||||||
@ -335,7 +365,7 @@ export default {
|
|||||||
let toScrollLeft = this.memorizedHorizontalLeft + dScrollLeft
|
let toScrollLeft = this.memorizedHorizontalLeft + dScrollLeft
|
||||||
toScrollLeft = Math.min(toScrollLeftUpperBound, toScrollLeft)
|
toScrollLeft = Math.min(toScrollLeftUpperBound, toScrollLeft)
|
||||||
toScrollLeft = Math.max(toScrollLeft, 0)
|
toScrollLeft = Math.max(toScrollLeft, 0)
|
||||||
this.$refs.scrollContainer.scrollLeft = toScrollLeft
|
this._container().scrollLeft = toScrollLeft
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
handleHorizontalScrollMouseUp (e) {
|
handleHorizontalScrollMouseUp (e) {
|
||||||
@ -366,7 +396,7 @@ export default {
|
|||||||
let toScrollTop = this.memorizedVerticalTop + dScrollTop
|
let toScrollTop = this.memorizedVerticalTop + dScrollTop
|
||||||
toScrollTop = Math.min(toScrollTopUpperBound, toScrollTop)
|
toScrollTop = Math.min(toScrollTopUpperBound, toScrollTop)
|
||||||
toScrollTop = Math.max(toScrollTop, 0)
|
toScrollTop = Math.max(toScrollTop, 0)
|
||||||
this.$refs.scrollContainer.scrollTop = toScrollTop
|
this._container().scrollTop = toScrollTop
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
handleVerticalScrollMouseUp (e) {
|
handleVerticalScrollMouseUp (e) {
|
||||||
|
Loading…
Reference in New Issue
Block a user