1. Component introduction
The Affix component is used to pin page elements to a specific visual area.
1.1 Properties
- position: Specify the position of the fixed nail, which can be set to top or bottom, and the default is top
- offset: Set the offset distance, default is 0
- target: Specify the container (CSS selector), so that the fixed nails are always kept in the container, and hidden if they are beyond the range. The default container is.
- z-index: The level of the fixed nail, default 100
1.2 Events
- scroll: An event is triggered when the container is scrolled, the parameters are: the scrollTop value and status of the fixed nail (whether it was fixed)
- Change: Triggered when the fixed nail state changes, the parameter is whether the fixed nail is currently in fixed state.
2. Source code analysis
2.1 template
<template> <div ref="root" class="el-affix" :style="rootStyle"> <div :class="{'el-affix--fixed': }" :style="affixStyle"> <slot></slot> </div> </div> </template>
The template part is simple, receive content through slot
2.2 script
// Some core codes have been adjusted in ordersetup(props, { emit }) { // target container ref const target = ref(null) // Site the ref, cooperate with the ref attribute in template to obtain HTML elements const root = ref(null) // Scroll container ref const scrollContainer = ref(null) // Stabilize const state = reactive({ fixed: false, height: 0, // height of root width: 0, // width of root scrollTop: 0, // scrollTop of documentElement clientHeight: 0, // clientHeight of documentElement transform: 0, }) onMounted(() => { // Determine the target container based on the incoming target if () { = () if (!) { throw new Error(`target is not existed: ${}`) } } else { = } // Looking up the scroll container according to the nail element = getScrollContainer() // Listen to scroll events of scroll containers on(, 'scroll', onScroll) // Listen to the resize event of the fixed nail element addResizeListener(, updateState) }) // Response function of scroll event of scroll container const onScroll = () => { // Update the fixed nail status updateState() emit('scroll', { scrollTop: , fixed: , }) } // Update the fixed nail state function const updateState = () => { const rootRect = () const targetRect = () = = = === window ? : = if ( === 'top') { if () { const difference = - - // > 0 Correspondingly, keep the fixed nail in the container always, and hide it if it exceeds the range = > && > 0 // Used to handle scenes: During the scrolling process, the visible area of the target container is not enough to display the entire solid nail, so the solid nail should be offset accordingly and only part of it is displayed. = difference < 0 ? difference : 0 } else { = > } } else { if () { const difference = - - - = - < && > = difference < 0 ? -difference : 0 } else { = - < } } } // Monitor the state changes of fixed nails and emit change events to externally watch(() => , () => { emit('change', ) }) // Calculate the attributes, automatically update the style of the fixed nail through the fixed nail status const affixStyle = computed(() => { if (!) { return } const offset = ? `${}px` : 0 const transform = ? `translateY(${}px)` : '' return { height: `${}px`, width: `${}px`, top: === 'top' ? offset : '', bottom: === 'bottom' ? offset : '', transform: transform, zIndex: , } }) }
2.3 Implementation summary:
- By listening to the scroll event of the scroll container (and the resize event of the fixing nail itself);
- In the event response function, dynamically obtains the DOM properties of the fixed nail and the target container and calculates the state of the fixed nail;
- Use computed properties to automatically update the style of the fixed nail;
This is the end of this article about Element Plus implementing Affix and GDing. For more related Element Affix content, please search for my previous articles or continue browsing the related articles below. I hope everyone will support me in the future!