使position: fixed的行为像sticky一样(适用于Vue2)

8

position: sticky在大多数移动浏览器上不被支持。但是position: fixed并不是我需要的东西(因为固定块会覆盖文档底部的内容)。

我猜对于jquery来说,如果我们在滚动时获取文档底部,很容易为固定块设置静态位置。

但是对于Vue2,我没有任何想法如何做到这一点。请给出一些建议。或者也许有更好的解决方案存在。


也许可以使用 https://www.npmjs.com/package/position-sticky。 - Roy J
或者 https://github.com/wilddeer/stickyfill - Roy J
我认为这不会起作用,因为以下库需要jquery,而不是Vuejs。 - Maria
我认为他们不需要jQuery。对于stickyfill,您只需要在创建元素后调用Stickyfill.add(elements);(最可能是在“mounted”钩子中)。 - Roy J
2个回答

15

正如我在评论中提到的,如果可能的话,我建议使用polyfill。他们会付出很多努力来做得正确。但是,这里有一个简单的方法,可以告诉你如何在Vue中实现它。

我通过将scrollY值放入数据项来处理应用程序中的滚动事件。我的sticky-top组件计算其固定顶部位置,并且如果它> 0,则使用它。该小部件为position:relative

new Vue({
  el: '#app',
  data: {
    scrollY: null
  },
  mounted() {
    window.addEventListener('scroll', (event) => {
      this.scrollY = Math.round(window.scrollY);
    });
  },
  components: {
    stickyTop: {
      template: '<div class="a-box" :style="myStyle"></div>',
      props: ['top', 'scrollY'],
      data() {
        return {
          myStyle: {},
          originalTop: 0
        }
      },
      mounted() {
        this.originalTop = this.$el.getBoundingClientRect().top;
      },
      watch: {
        scrollY(newValue) {
          const rect = this.$el.getBoundingClientRect();
          const newTop = this.scrollY + +this.top - this.originalTop;

          if (newTop > 0) {
            this.$set(this.myStyle, 'top', `${newTop}px`);
          } else {
            this.$delete(this.myStyle, 'top');
          }
        }
      }
    }
  }
});
#app {
  height: 1200px;
}

.spacer {
  height: 80px;
}

.a-box {
  display: inline-block;
  height: 5rem;
  width: 5rem;
  border: 2px solid blue;
  position: relative;
}
<script src="//unpkg.com/vue@latest/dist/vue.js"></script>
<div id="app">
  <div class="spacer"></div>
  <div class="a-box"></div>
  <sticky-top top="20" :scroll-y="scrollY"></sticky-top>
  <div class="a-box"></div>
</div>


1
@Boern,为什么你撤销了答案并包含了未使用的变量? - Roy J
1
哈哈 :) 因为还有更多内容,我既不想发布不完整的修订版,也没有信心在没有得到你的同意的情况下修改大部分你的代码(我是JS新手)。此外,我也不想提交自己的解决方案并窃取你的声誉。 - Boern

0

这对我来说似乎有效

...

  <header
    ref="header"
    class="header-container"
    :class="{ 'header-container--sticky': isHeaderSticky }"
  >

...

...

data() {
    return{
      scrollY: null,
      headerTop: 0,
      isHeaderSticky: false,
    }
  },
  mounted() {
    window.addEventListener('load', () => {
      window.addEventListener('scroll', () => {
        this.scrollY = Math.round(window.scrollY);
      });
      this.headerTop = this.$refs.header.getBoundingClientRect().top;
    });
  },
  watch: {
    scrollY(newValue) {
      if (newValue > this.headerTop) {
        this.isHeaderSticky = true;
      } else {
        this.isHeaderSticky = false;
      }
    }
  }

...

...

.header-container {
      &--sticky {
        position: sticky;
        top: 0;
        z-index: 9999;
      }
    }

...


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接