要想实现一个吸顶效果不是很难,网络上有很多教程,其中有一种就是通过fiexd加top来实现,今天突然就想做一个吸顶效果,因为最近都在用vue,所以想用vue来做一个吸顶效果的案例。
实现思路
- 获取当前dom节点相对offsetParent的offsetTop,将这个offsetTop保存起来(防止当前dom的position为fixed时导致offsetTop重置为0)。
- 监听页面滑动距离,当滑动距离-offsetTop>0的时候,当前dom节点就吸顶,反之恢复之前状态。
话不多说上代码:
export default {
stick: {
bind: (el, binding, vnode) => {
let oldOffsetTop = null; // 保存当前元素的offsetTop,防止吸顶后offsetTop重置为0
addEventListener('scroll', e => {
const scrollTop = window.pageYoffset || document.documentElement.scrollTop || document.body.scrollTop// 滚动距离
const { offsetTop } = el // 元素距离offsetParent的距离
if (!oldOffsetTop) oldOffsetTop = offsetTop
if (scrollTop - oldOffsetTop > 0) {
el.style.position = 'fixed'
if (binding.value) {
el.style.top = binding.value + 'px'
} else {
el.style.top = '0px'
}
} else {
if (el.style.position === 'fixed') {
el.style.position = 'static'
}
}
})
}
}
}
上述代码实现了一个吸顶效果的vue指令,最后只需要在main.js文件中将这个指令注册即可使用。
main.js文件中加入
import directive from './common/directive'
for (const key in directive) {
Vue.directive(key, directive[key])
}
使用方式:
<li class="stick" v-stick>吸顶效果指令</li>
或者加入偏移量
<li class="stick" v-stick="100">吸顶效果指令</li>
<template>
<div id="app">
<!-- <starrySky /> -->
<div class="p"></div>
<ul>
<li>1</li>
<li>1</li>
<li>1</li>
<li>1</li>
<li>1</li>
<li>1</li>
<li>1</li>
<li>1</li>
<li>1</li>
<li>1</li>
<li>1222222</li>
<li class="stick" v-stick>吸顶效果指令</li>
<li>12222222</li>
<li>1</li>
<li>1</li>
<li>1</li>
<li>1</li>
<li>1</li>
<li>1</li>
<li>1</li>
</ul>
</div>
</template>
<script>
export default {
components: {
}
}
</script>
<style>
#app {
}
.p {
height: 100vh;
}
ul {
}
li{
padding: 30px;
}
</style>