前言
在移動端中,吸頂效果非常常見
不同組件多次使用的話,建議在 src 下新建一個 common 文件夾,創建 stickySlot.vue 文件,方便多次複用
組件中使用
爲了方便演示,這裏使用了for循環的方法將屏幕撐滿,直接將全部代碼複製運行就能看到效果
<template>
<div>
<ul>
<li v-for="(item, index) in headerData" :key="index">{{ item }}</li>
</ul>
<!--
這裏需要給組件添加一個class,用於控制固定的位置,看css註釋部分
-->
<sticky-slot class="stickyTop">
<div class="tab">
假裝這是一個tab欄,當頁面滾動的時候要固定在頂部
</div>
</sticky-slot>
<ul>
<li v-for="(item, index) in footerData" :key="index">{{ item }}</li>
</ul>
</div>
</template>
<script>
import stickySlot from '@/common/stickySlot.vue' // 需改爲對應的組件存放的路徑
export default {
components: {
stickySlot
},
data() {
return {
headerData: [],
footerData: []
};
},
created() {
// 使用假數據撐滿屏幕
for (let i = 0; i < 20; i++) {
this.headerData.push('第' + i + '條數據')
};
for (let i = 20; i < 80; i++) {
this.footerData.push('第' + i + '條數據')
}
}
}
</script>
<style>
/*
通過設置top的值,控制固定的位置,0是頂部,值爲number(px)
*/
.stickyTop {
top: 0;
z-index: 10;
}
.tab {
height: 30px;
line-height: 30px;
background-color: greenyellow;
}
</style>
效果圖
到達頂部的時候固定在頂部,內容部分繼續滾動
stickySlot.vue源碼
<template>
<div class="sticky" :style="getPosition">
<div class="sticky-warp">
<slot></slot>
</div>
</div>
</template>
<script type="text/babel">
export default {
data () {
return {}
},
computed: {
getPosition(){
var position = this.cssSupport('position', 'sticky') ? 'sticky' : 'relative';
return 'position:' + position;
}
},
props: {},
beforeMount () {
},
mounted(){
this.init();
},
deactivated(){
if(this.cssSupport('position', 'sticky')) {
return;
}
/*復位*/
var elWarp = this.$el.querySelector('.sticky-warp');
elWarp.position = 'absolute';
},
methods: {
init(){
if (this.cssSupport('position', 'sticky')) {
return;
}
var el = this.$el, target = this.$el.parentNode,
elWarp = this.$el.querySelector('.sticky-warp'),
top = this.getNumberValue(document.defaultView.getComputedStyle(el).top);
this.addScrollListen(target, (event)=> {
if (el.getBoundingClientRect().top <= top) {
elWarp.style.position = 'fixed';
}
if (el.getBoundingClientRect().top >= 0 && elWarp.style.position != 'absolute') {
elWarp.style.position = 'absolute';
}
})
},
cssSupport: function (attr, value) {
var element = document.createElement('div');
if (attr in element.style) {
element.style[attr] = value;
return element.style[attr] === value;
} else {
return false;
}
},
getNumberValue(pxValue){
var value = String(pxValue).match(/^\-?\+?[0-9]+/g);
return value ? Number(value) : undefined;
},
addScrollListen(target, cb){
target.addEventListener('y-scroll', (event)=> {
cb && cb(event);
});
}
},
}
</script>
<style>
.sticky {
width: 100%;
}
.sticky .sticky-warp {
width: 100%;
background: inherit;
will-change: change;
height: inherit;
top: inherit;
}
</style>
如果本篇文章對你有幫助的話,很高興能夠幫助上你。
當然,如果你覺得文章有什麼讓你覺得不合理、或者有更簡單的實現方法又或者有理解不來的地方,希望你在看到之後能夠在評論裏指出來,我會在看到之後儘快的回覆你。