UNPKG

@minix-iot/ui

Version:

基于Vue的移动端轻量级UI组件库

116 lines (110 loc) 3.53 kB
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> ) } }