123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148 |
- <template>
- <div ref="placeholderNode" :style="{ ...placeholderNodeStyle }">
- <div ref="fixedNode" :style="{ ...fixedNodeStyle }">
- <slot />
- </div>
- </div>
- </template>
- <script>
- import { TRIGGER_EVENTS, getDefaultTarget } from './utils'
- import addDOMEventListener from 'add-dom-event-listener'
- import _ from 'lodash'
- export default {
- name: 'Affix',
- props: {
- /**
- * 距离窗口顶部达到指定偏移量后触发
- */
- offsetTop: {
- type: Number,
- required: false,
- default: () => null
- },
- offset: {
- type: Number,
- required: false,
- default: () => null
- },
- /** 距离窗口底部达到指定偏移量后触发 */
- offsetBottom: {
- type: Number,
- required: false,
- default: () => null
- },
- /** 固定状态改变时触发的回调函数 */
- // onChange?: (_Affixed?: boolean) => void;
- /** 设置 _Affix 需要监听其滚动事件的元素,值为一个返回对应 DOM 元素的函数 */
- target: {
- type: Function,
- required: false,
- default: () => getDefaultTarget()
- },
- prefixCls: {
- type: String,
- required: false,
- default: () => null
- }
- },
- data() {
- this.lazyUpdatePosition = _.throttle(this.lazyUpdatePosition, 300)
- return {
- placeholderNodeStyle: '',
- fixedNodeStyle: '',
- entity: {
- target: null,
- affixList: [],
- eventHandlers: {}
- }
- }
- },
- mounted() {
- // console.log(this.target().Target)
- this.init()
- },
- // 销毁事件
- destroyed() {
- this.unInit()
- },
- methods: {
- init() {
- const { entity } = this
- const targetNode = this.target()
- TRIGGER_EVENTS.forEach((eventName) => {
- // targetNode.addEventListener(eventName, () => {
- // this.lazyUpdatePosition()
- // })
- entity.eventHandlers[eventName] = addDOMEventListener(
- targetNode,
- eventName,
- () => {
- this.lazyUpdatePosition()
- }
- )
- })
- this.lazyUpdatePosition()
- },
- // @ts-ignore TS6133
- prepareMeasure() {
- this.fixedNodeStyle = null
- this.placeholderNodeStyle = null
- this.$forceUpdate()
- },
- getOffsetTop() {
- const { offset, offsetBottom } = this
- let { offsetTop } = this
- if (typeof offsetTop === 'undefined') {
- offsetTop = offset
- }
- if (offsetBottom === undefined && offsetTop === undefined) {
- offsetTop = 0
- }
- return offsetTop
- },
- lazyUpdatePosition() {
- const targetNode = this.target()
- const offsetTop = this.getOffsetTop()
- // console.log(102, this.$refs, targetNode.scrollTop)
- if (targetNode.scrollTop < offsetTop) {
- this.prepareMeasure()
- return
- }
- const placeholderReact = this.$refs.placeholderNode
- this.fixedNodeStyle = {
- position: 'fixed',
- top: `${offsetTop}px`,
- zIndex: 999,
- width: placeholderReact.offsetWidth + 'px',
- height: placeholderReact.offsetHeight + 'px'
- }
- this.placeholderNodeStyle = {
- width: placeholderReact.offsetWidth + 'px',
- height: placeholderReact.offsetHeight + 'px'
- }
- },
- unInit() {
- const { entity } = this
- // const targetNode = this.target()
- // console.log(123, targetNode)
- TRIGGER_EVENTS.forEach((eventName) => {
- // targetNode.removeEventListener(eventName, () => {
- // this.lazyUpdatePosition()
- // })
- // entity.eventHandlers[eventName]
- const handler = entity.eventHandlers[eventName]
- if (handler && handler.remove) {
- handler.remove()
- }
- })
- }
- }
- }
- </script>
- <style scoped lang="less"></style>
|