vue 移動端吸頂效果,開始隨頁面滾動,滾動到指定位置固定在頂部或者固定在指定位置

前言

在移動端中,吸頂效果非常常見
不同組件多次使用的話,建議在 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>

如果本篇文章對你有幫助的話,很高興能夠幫助上你。

當然,如果你覺得文章有什麼讓你覺得不合理、或者有更簡單的實現方法又或者有理解不來的地方,希望你在看到之後能夠在評論裏指出來,我會在看到之後儘快的回覆你。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章