Eugene Yermolaev
Eugene Yermolaev

Reputation: 21

Vue JS removeEventListener not working. Why?

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

This line is not working, why? window.removeEventListener("scroll", handler, false); I tried all approaches: arrow function, function declaration, etc. But that event listener is not removing at all.

Upvotes: 2

Views: 5390

Answers (2)

I had a similar problem, in the end, I solved it with another alternative, adding the once option in the parameters of the addEventListener function that removes it automatically and it was valid for me, in the case can help you check the parameters

Upvotes: 2

Terry
Terry

Reputation: 66093

It seems like you've slightly overcomplicated your logic. Like what Bravo has mentioned in the comment, you will need a static reference to the handler for it to be unbound: you can simply declare it as a component method. Here's how you can update your code:

  1. Use onScroll() method to handle the logic on scroll. You simply pass this method reference in your add/remove event listener
  2. You should cache your lastScrollTop as part of the component data. 3, Then, you simply add the scroll event listener in the mounted() lifecycle hook, and remove it in the destroyed() lifecycle hook.

See updated code below:

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

Upvotes: 0

Related Questions