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>
 |