Наблюдайте за изменениями window.scrollY в Vuejs

У меня есть очень простое приложение, состоящее из 2 компонентов: App.vue и другого компонента Home.vue, в котором я храню остальную часть структуры приложения: липкий заголовок и несколько разделов с якорями для прокрутки.

Я хочу применить класс к липкому заголовку, чтобы свернуть логотип во время прокрутки страницы. Поэтому я подумал, что буду следить за любыми изменениями в window.scrollY. Поэтому, если scrollY больше 0, примените класс, который минимизирует логотип.

Я пытался прослушивать события прокрутки в своем компоненте, но это не зашло слишком далеко. В этом обсуждении здесь представлено очень хорошее решение, но я не знаю, где разместить событие прокрутки. https://github.com/vuejs/Обсуждение/issues/324

Итак, я подумал, что наиболее подходящим решением будет создать свойство данных, присвоить ему число window.scrollY и затем следить за изменениями его значения. К сожалению, наблюдатель никогда не срабатывает. Так что теперь я застрял. Код:

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

Любые идеи о том, что я могу делать неправильно?

Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
9
0
16 281
5
Перейти к ответу Данный вопрос помечен как решенный

Ответы 5

Ответ принят как подходящий

window свойства нельзя использовать реактивно таким образом. Вместо этого вам нужно будет прослушать событие 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 */
  }
}

Edit Watching scrollTop in Vue

Вы можете использовать метод mounted(), чтобы добавить прослушиватель событий к объекту окна следующим образом:

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>

2020 Обновлено:

Используйте @scroll.passive для просмотра прокрутки любого элемента в компоненте:

Пример:

Шаблон

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

Методы:

handleScroll (e) {
  var scrollPos = e.target.scrollTop
}
scroll события не могут быть preventDefaulted, поэтому флаг passive здесь не поможет. Флаг обычно используется для улучшить производительность прокрутки для дорогостоящих обработчиков событий touchstart/touchmove.
tony19 13.05.2021 00:21

Для меня ничего из вышеперечисленного не сработало.

Мне пришлось передать true в качестве третьего параметра в прослушивателе добавления/удаления прокрутки:

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

3-й параметр: У вас должна быть возможность подключить прослушиватель на уровне документа с третьим параметром true для захвата событий прокрутки для всех элементов. Вот как это выглядит:

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

Значение true в конце является важной частью, оно сообщает браузеру, что нужно захватить событие при отправке, даже если это событие обычно не всплывает, например изменение, фокус и прокрутка.

Я пытался сделать что-то, где мне просто нужно вызвать переменную или функцию, чтобы получить позицию прокрутки окна в любом компоненте. Поэтому, чтобы добиться этого, я в конечном итоге использую миксины. Вот мой код. Я использую нуст.

Внутри плагина создайте файл, например. прокрутка-position.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
        }
    }
})

В nuxt.config.js

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

Теперь вы можете использовать get_scroll_position() в любом компоненте. Что-то вроде этого

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

Другие вопросы по теме