简体   繁体   English

观察 Vuejs 中 window.scrollY 的变化

[英]Watch window.scrollY changes in Vuejs

I have a very simple app, that has 2 components: the App.vue and another component, Home.vue where I hold the rest of the structure of the app: a sticky header and some sections with anchors to scroll to.我有一个非常简单的应用程序,它有 2 个组件: App.vue和另一个组件Home.vue ,我在其中保存了应用程序的其余结构:一个粘性标题和一些带有可滚动到的锚点的部分。

I want to apply a class to the sticky header to minimize the logo while the page is scrolled.我想对粘性标题应用一个类,以在滚动页面时最小化徽标。 So I thought I'd watch for any changes in window.scrollY .所以我想我会注意window.scrollY任何变化。 So if scrollY is greater than 0, apply some class that minimizes the logo.因此,如果scrollY大于 0,则应用一些最小化徽标的类。

I tried to listen to scroll events in my component, but that didn't go very far.我试图在我的组件中监听滚动事件,但这并没有走多远。 In this discussion here, a very good solution is provided, but I don't know where to place the scroll event.在这里的这个讨论中,提供了一个非常好的解决方案,但我不知道在哪里放置滚动事件。 https://github.com/vuejs/Discussion/issues/324 https://github.com/vuejs/Discussion/issues/324

So, I thought the most fitting solution would be to create a data property, assign it the window.scrollY figure and then watch for changes in its value.所以,我认为最合适的解决方案是创建一个数据属性,将其分配给window.scrollY图,然后观察其值的变化。 Unfortunately, the watcher is never triggered.不幸的是,观察者从未被触发。 So now I'm stuck.所以现在我被困住了。 The code is:代码是:

data () {
return {
  ...
  windowTop: window.top.scrollY
 }
}
...
watch: {
 windowTop: {
  immediate: true,
  handler (newVal, oldVal) {
    console.log(newVal, oldVal);
  },
 }
}

Any ideas of what I might be doing wrong?关于我可能做错了什么的任何想法?

window properties can't be used reactively like that.不能像那样被动地使用window属性。 Instead, you'd have to listen to the window 's scroll event and respond accordingly:相反,您必须监听windowscroll事件并做出相应的响应:

mounted() {
  window.addEventListener("scroll", this.onScroll)
},
beforeDestroy() {
  window.removeEventListener("scroll", this.onScroll)
},
methods: {
  onScroll(e) {
    this.windowTop = window.top.scrollY /* or: e.target.documentElement.scrollTop */
  }
}

在 Vue 中编辑 Watching scrollTop

For me none of the above worked.对我来说,以上都没有奏效。

I had to pass true as 3rd parameter in add/remove scroll listener:我必须在添加/删除滚动侦听器中将true作为第三个参数传递:

mounted() {
  window.addEventListener("scroll", this.onScroll, true)
},
beforeDestroy() {
  window.removeEventListener("scroll", this.onScroll, true)
},
methods: {
  onScroll(e) {
    this.windowTop = e.target.scrollTop;
  }
}

3rd parameter: You should be able to attach a document-level listener with a third parameter of true to capture the scroll events on all elements.第三个参数:您应该能够使用第三个参数为 true 的文档级侦听器来捕获所有元素上的滚动事件。 Here's what that looks like:这是它的样子:

document.addEventListener('scroll', function(e){ }, true);

The true at the end is the important part, it tells the browser to capture the event on dispatch, even if that event does not normally bubble, like change, focus, and scroll.最后的 true 是重要的部分,它告诉浏览器在调度时捕获事件,即使该事件通常不会冒泡,如更改、焦点和滚动。

2020 Updated: 2020 更新:

Use @scroll.passive to watch scroll of any element in component:使用@scroll.passive观察组件中任何元素的滚动:

Example:例子:

Template模板

<div class="room_message-stream" @scroll.passive="handleScroll">
      <ul class="room_message-stream__list">
        <li class="room_message-stream__list-item">...</li>
      </ul>
</div>

Methods:方法:

handleScroll (e) {
  var scrollPos = e.target.scrollTop
}

You can use the mounted() method to add your event listener to the window object like this:您可以使用mounted()方法将事件侦听器添加到 window 对象,如下所示:

 var p = new Vue({ el: "#app", data(){ return { windowTop: 0 }; }, mounted() { var that = this; window.addEventListener("scroll", function(){ that.windowTop = window.scrollY; }); }, template: "<div style='height: 250vh'><div style='position: fixed; right: 0; top: 0'>{{windowTop}}</div></div>" });
 <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script> <div id="app"></div>

I was trying to do something where I just have to call a variable or function to get the window scroll position in any component.我试图做一些事情,我只需要调用一个变量或函数来获取任何组件中的窗口滚动位置。 So in order to achieve that I end up using mixins.所以为了实现这一点,我最终使用了 mixins。 Here is my code.这是我的代码。 I am using nuxt.我正在使用 nuxt。

Inside plugin create a file eg.在插件内部创建一个文件,例如。 scroll-position.js滚动位置.js

import Vue from 'vue'

Vue.mixin({
    data() {
        return {
            scrollPosition: window.scrollY
        }
    },
    methods: {
        get_scroll_position() {
            window.addEventListener('scroll', () => {
                this.scrollPosition = window.scrollY;
            });
            return this.scrollPosition
        }
    }
})

In nuxt.config.js在 nuxt.config.js 中

plugins:['@/plugins/scroll-position.js']

Now you can use get_scroll_position() in any component you want Something like this现在你可以在任何你想要的组件中使用 get_scroll_position() 类似这样的

:class="{'header_sticky':get_scroll_position()>=80}"

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM