@minix-iot/ui
Version:
基于Vue的移动端轻量级UI组件库
116 lines (110 loc) • 3.53 kB
JSX
import { Namespace } from "../../utils/namespace";
import { DOMExtension } from "../../utils/extensions/dom";
const namesapce = Namespace.Create('sticky')
export default {
name: namesapce.name,
props:{
position:{
type: String,
default:'top'
},
zIndex:{
type: Number | String,
default: 1060
},
offset:{
type: Number,
default:0
},
container:{
type: Node
}
},
data(){
return {
fixed: false,
width:0,
height:0,
transform:0,
scrollParent: null
}
},
computed:{
rootStyle(){
if(this.fixed){
return {
width: `${this.width}px`,
height: `${this.height}px`
}
}
},
cls(){
return namesapce.derive({
fixed: this.fixed
})
},
style(){
if(!this.fixed){
return
}
const res = {
zIndex: this.zIndex,
width: `${this.width}px`,
height: `${this.height}px`,
[this.position]: `${this.offset}px`
}
if(this.transform){
res.transform = `translate3d(0,${this.transform}px,0)`
}
return res
}
},
mounted(){
this.scrollParent = DOMExtension.GetScrollParent(this.$el)
DOMExtension.AddEventListener(this.scrollParent,'scroll', this.onScroll)
},
beforeDestory(){
DOMExtension.RemoveEventListener(this.scrollParent,'scroll', this.onScroll)
},
methods:{
onScroll(e){
const {position, container} = this.$props
const rootRect = DOMExtension.GetBoundingClientRect(this.$el)
this.width = rootRect.width
this.height = rootRect.height
if(position === 'top'){
if(container){
const containerRect = DOMExtension.GetBoundingClientRect(container)
this.fixed = this.offset > rootRect.top && containerRect.bottom > 0
const delta = containerRect.bottom - this.offset - this.height
this.transform = delta < 0 ? delta : 0
}else{
this.fixed = this.offset > rootRect.top
}
}else{
const {clientHeight} = document.documentElement
if(container){
const containerRect = DOMExtension.GetBoundingClientRect(container)
this.fixed = (clientHeight - this.offset < rootRect.bottom) && clientHeight > containerRect.top
const delta = clientHeight - containerRect.top - this.height - this.offset
this.transform = delta < 0 ? -delta : 0
}else{
this.fixed = clientHeight - this.offset < rootRect.bottom
}
}
this.$emit('scroll',{
scrollTop : DOMExtension.GetScrollTop(this.scrollParent),
isFixed: this.fixed
})
}
},
render(){
return (
<div style={this.rootStyle}>
<div class={this.cls} style={this.style}>
{this.$slots.default}
</div>
</div>
)
}
}