vue 移动端吸顶效果,开始随页面滚动,滚动到指定位置固定在顶部或者固定在指定位置

前言

不同组件多次使用的话,建议在 src 下新建一个 common 文件夹,创建 stickySlot.vue 文件,方便多次复用

组件中使用

为了方便演示,这里使用了for循环的方法将屏幕撑满,直接将全部代码复制运行就能看到效果

<template>
  <div>
    <ul>
      <li v-for="(item, index) in headerData" :key="index">{{ item }}li>
    ul>
    
    <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 scoped>
  /* 
    通过设置top的值,控制需要固定在什么位置,0是顶部,值为number(px)
  */
  .stickyTop {
    top: 0;
    z-index: 10;
  }
  .tab {
    height: 30px;
    line-height: 30px;
    background-color: greenyellow;
  }
style>

效果图

vue 移动端吸顶效果,开始随页面滚动,滚动到指定位置固定在顶部或者固定在指定位置_第1张图片

到达顶部的时候固定在顶部,内容部分继续滚动

vue 移动端吸顶效果,开始随页面滚动,滚动到指定位置固定在顶部或者固定在指定位置_第2张图片

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;
      }
    },
    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(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>

如果本篇文章对你有帮助的话,很高兴能够帮助上你。

当然,如果你觉得文章有什么让你觉得不合理、或者有更简单的实现方法又或者有理解不来的地方,希望你在看到之后能够在评论里指出来,我会在看到之后尽快的回复你。

你可能感兴趣的:(vue,javaScript,H5)