92 lines
		
	
	
		
			2.0 KiB
		
	
	
	
		
			Plaintext
		
	
	
			
		
		
	
	
			92 lines
		
	
	
		
			2.0 KiB
		
	
	
	
		
			Plaintext
		
	
	
| <template>
 | |
|   <div :style="{height:height+'px',zIndex:zIndex}">
 | |
|     <div
 | |
|       :class="className"
 | |
|       :style="{top:(isSticky ? stickyTop +'px' : ''),zIndex:zIndex,position:position,width:width,height:height+'px'}"
 | |
|     >
 | |
|       <slot>
 | |
|         <div>sticky</div>
 | |
|       </slot>
 | |
|     </div>
 | |
|   </div>
 | |
| </template>
 | |
| 
 | |
| <script>
 | |
| export default {
 | |
|   name: 'Sticky',
 | |
|   props: {
 | |
|     stickyTop: {
 | |
|       type: Number,
 | |
|       default: 0
 | |
|     },
 | |
|     zIndex: {
 | |
|       type: Number,
 | |
|       default: 1
 | |
|     },
 | |
|     className: {
 | |
|       type: String,
 | |
|       default: ''
 | |
|     }
 | |
|   },
 | |
|   data() {
 | |
|     return {
 | |
|       active: false,
 | |
|       position: '',
 | |
|       width: undefined,
 | |
|       height: undefined,
 | |
|       isSticky: false
 | |
|     }
 | |
|   },
 | |
|   mounted() {
 | |
|     this.height = this.$el.getBoundingClientRect().height
 | |
|     window.addEventListener('scroll', this.handleScroll)
 | |
|     window.addEventListener('resize', this.handleResize)
 | |
|   },
 | |
|   activated() {
 | |
|     this.handleScroll()
 | |
|   },
 | |
|   destroyed() {
 | |
|     window.removeEventListener('scroll', this.handleScroll)
 | |
|     window.removeEventListener('resize', this.handleResize)
 | |
|   },
 | |
|   methods: {
 | |
|     sticky() {
 | |
|       if (this.active) {
 | |
|         return
 | |
|       }
 | |
|       this.position = 'fixed'
 | |
|       this.active = true
 | |
|       this.width = this.width + 'px'
 | |
|       this.isSticky = true
 | |
|     },
 | |
|     handleReset() {
 | |
|       if (!this.active) {
 | |
|         return
 | |
|       }
 | |
|       this.reset()
 | |
|     },
 | |
|     reset() {
 | |
|       this.position = ''
 | |
|       this.width = 'auto'
 | |
|       this.active = false
 | |
|       this.isSticky = false
 | |
|     },
 | |
|     handleScroll() {
 | |
|       const width = this.$el.getBoundingClientRect().width
 | |
|       this.width = width || 'auto'
 | |
|       const offsetTop = this.$el.getBoundingClientRect().top
 | |
|       if (offsetTop < this.stickyTop) {
 | |
|         this.sticky()
 | |
|         return
 | |
|       }
 | |
|       this.handleReset()
 | |
|     },
 | |
|     handleResize() {
 | |
|       if (this.isSticky) {
 | |
|         this.width = this.$el.getBoundingClientRect().width + 'px'
 | |
|       }
 | |
|     }
 | |
|   }
 | |
| }
 | |
| </script>
 |