Vue JS removeEventListener не работает. Почему?

const options = {
  offset: -50
};

export default {
  name: 'BarMenu',
  data() {
    return {
      scrollingDirection: '',
    }
  },
  computed: {
    cssClasses() {
      return {
        hidden: this.scrollingDirection === 'down'
      }
    }
  },
  mounted() {
    this.onScroll();
  },
  methods: {
    scrollToIngredients() {
      return this.$scrollTo(document.getElementById('ingredients-inside-content'), 600, options);
    },
    scrollToRecipes() {
      return this.$scrollTo(document.getElementById('similar-recipes'), 600, options);
    },
    scrollToComments() {
      return this.$scrollTo(document.getElementById('comments'), 600, options);
    },
    onScroll() {
      let lastScrollTop = 0;

      const handler = () => {
        let st = window.pageYOffset || document.documentElement.scrollTop;
        if (st > lastScrollTop) {
          this.scrollingDirection = 'down';
        } else {
          this.scrollingDirection = 'up';
        }
        lastScrollTop = st <= 0 ? 0 : st;
      };

      window.removeEventListener("scroll", handler, false);
      window.addEventListener("scroll", handler, false);
    }
  },
}

Эта линия не работает, почему? window.removeEventListener("scroll", handler, false); Я перепробовал все подходы: стрелочную функцию, объявление функции и т. Д. Но этот прослушиватель событий вообще не удаляет.


person Eugene Yermolaev    schedule 22.11.2019    source источник
comment
Вы удаляете обработчик и в следующей строке снова добавляете его. Вы действительно этого хотите? Пожалуйста, будьте более конкретными.   -  person str    schedule 22.11.2019
comment
handler не будет одинаковым handler каждый раз при запуске scroll - поэтому, если ваш код пытается удалить старый обработчик и заменить его, это не сработает - вы можете вместо этого сделать handler метод (хотя сделайте его обычной функцией , а не arrow function - однако, почему вам нужно менять обработчик на один и тот же код каждый раз, когда вы запускаете onScroll, остается загадкой.   -  person Bravo    schedule 22.11.2019
comment
Я хочу удалить этот прослушиватель событий, когда компонент разрушен. Я попытался выполнить это внутри обработчика жизненного цикла beforeDestroy, но он не работал.   -  person Eugene Yermolaev    schedule 22.11.2019


Ответы (2)


У меня была аналогичная проблема, в конце концов, я решил ее другой альтернативой, добавив параметр once в параметры функции addEventListener, которая удаляет его автоматически, и это было действительным для меня, в случае, если это может помочь вам проверить параметры

person franciscorode    schedule 25.10.2020

Похоже, вы немного усложнили свою логику. Как и то, что Браво упомянул в комментарии, вам понадобится статическая ссылка на обработчик, чтобы он не был привязан: вы можете просто объявить его как компонентный метод. Вот как вы можете обновить свой код:

  1. Используйте метод onScroll() для обработки логики прокрутки. Вы просто передаете ссылку на этот метод в слушателе событий добавления / удаления.
  2. Вы должны кэшировать свой lastScrollTop как часть данных компонента. 3. Затем вы просто добавляете прослушиватель событий прокрутки в ловушку жизненного цикла mounted() и удаляете ее в ловушке жизненного цикла destroyed().

См. Обновленный код ниже:

const options = {
  offset: -50
};

export default {
  name: 'BarMenu',
  data() {
    return {
      scrollingDirection: '',
      lastScrollTop: 0,
    }
  },
  computed: {
    cssClasses() {
      return {
        hidden: this.scrollingDirection === 'down'
      }
    }
  },
  mounted() {
    window.addEventListener("scroll", this.onScroll, false);
  },
  destroyed() {
    window.removeEventListener("scroll", this.onScroll, false);
  },
  methods: {
    scrollToIngredients() {
      return this.$scrollTo(document.getElementById('ingredients-inside-content'), 600, options);
    },
    scrollToRecipes() {
      return this.$scrollTo(document.getElementById('similar-recipes'), 600, options);
    },
    scrollToComments() {
      return this.$scrollTo(document.getElementById('comments'), 600, options);
    },
    onScroll() {
      let st = window.pageYOffset || document.documentElement.scrollTop;
      if (st > this.lastScrollTop) {
        this.scrollingDirection = 'down';
      } else {
        this.scrollingDirection = 'up';
      }
      this.lastScrollTop = st <= 0 ? 0 : st;
    }
  },
}
person Terry    schedule 22.11.2019