| <!-- |
| |
| Licensed under the Apache License, Version 2.0 (the "License"); |
| you may not use this file except in compliance with the License. |
| You may obtain a copy of the License at |
| |
| http://www.apache.org/licenses/LICENSE-2.0 |
| |
| Unless required by applicable law or agreed to in writing, software |
| distributed under the License is distributed on an "AS IS" BASIS, |
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| See the License for the specific language governing permissions and |
| limitations under the License. |
| |
| --> |
| <template> |
| <div :style="{height:height+'px',zIndex:zIndex}"> |
| <div :class="className" :style="{top: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.handleReize) |
| }, |
| activated() { |
| this.handleScroll() |
| }, |
| destroyed() { |
| window.removeEventListener('scroll', this.handleScroll) |
| window.removeEventListener('resize', this.handleReize) |
| }, |
| methods: { |
| sticky() { |
| if (this.active) { |
| return |
| } |
| this.position = 'fixed' |
| this.active = true |
| this.width = this.width + 'px' |
| this.isSticky = true |
| }, |
| reset() { |
| if (!this.active) { |
| return |
| } |
| this.position = '' |
| this.width = 'auto' |
| this.active = false |
| this.isSticky = false |
| }, |
| handleScroll() { |
| this.width = this.$el.getBoundingClientRect().width |
| const offsetTop = this.$el.getBoundingClientRect().top |
| if (offsetTop < this.stickyTop) { |
| this.sticky() |
| return |
| } |
| this.reset() |
| }, |
| handleReize() { |
| if (this.isSticky) { |
| this.width = this.$el.getBoundingClientRect().width + 'px' |
| } |
| } |
| } |
| } |
| </script> |