2

I'm trying to add a class to the header on scroll and remove it. But fail. The class gets added at each scroll. So if ScrollY === 100, the element has added class 100 times. How to make it add just once, and remove it when the scrollY < 100?

What am I doing wrong?

Codepen

<div id="app">
  <v-app>
    <v-content>
      <v-container fluid fill-height class="priceContainer">
      <v-layout row wrap align-center justify-center>
        <v-flex xs12 sm12  text-center>
         <v-toolbar
      :clipped-left="$vuetify.breakpoint.lgAndUp"
      class="elevation-0 "
      fixed
      temporary
      @scroll="handleSCroll"
    >
      <v-toolbar-side-icon @click.stop="drawer = !drawer" ></v-toolbar-side-icon>
      <v-toolbar-title style="width: 300px" class="ml-0 pl-3">
        <span class="PriceLogoTitle hidden-sm-and-up">ELS</span>
        <span class="PriceLogoTitle hidden-sm-and-down">ELS</span>
      </v-toolbar-title>
      <v-spacer></v-spacer>
      <!-- кнопка входа -->
      <v-btn  class="navBtnEnter" flat>Enter <v-icon  right >account_box</v-icon></v-btn>
      <!-- кнопка входа конец -->
    </v-toolbar>
        </v-flex>   


        <!--  -->

      </v-layout>
    </v-container>
    </v-content>
  </v-app>
</div>


.priceContainer{
  background-image: radial-gradient( rgb(3, 237, 245),rgb(0, 126, 131));
  height: 1000px;
}
.theme--light.v-toolbar--bgchange {
    background-color: #009D95;
}

new Vue({
  el: '#app',
  methods:{
      handleSCroll (event) {
        let header = document.querySelector(".v-toolbar");
        if (window.scrollY > 100) {
        console.log(window.scrollY);
        header.className += " v-toolbar--bgchange";          
        }
      }
    },
    created () {
      window.addEventListener('scroll', this.handleSCroll);

    },
    destroyed () {
      window.removeEventListener('scroll', this.handleSCroll);
    } 
})

2 Answers 2

6

className is a string that can be set arbitrarily, and duplicate classes are not filtered out. On the other hand, classList.add() ignores duplicate class names, so you could replace the following:

header.className += " v-toolbar--bgchange";

with:

header.classList.add("v-toolbar--bgchange");

Removing the class is done with classList.remove("v-toolbar--bgchange").

Sign up to request clarification or add additional context in comments.

Comments

2

Vue is Reactive, so why to change DOM directly? Let's do it the way it likes :)

<template lang="pug">
  .main-nav(:class="getMainNavClasses")
    // your fancy stuff goes here ;)
</template>

<script>
export default {
  name: 'MainMenu',

  data() {
    return {
      scrollingUp: false,
      scrollingDown: false,
      prevScrollpos: window.pageYOffset,
    };
  },

  computed: {
    getMainNavClasses() {
      return {
        'scroll-up': this.scrollingUp,
        'scroll-down': this.scrollingDown,
      };
    },
  },

  methods: {
    scrollNow() {
      const currentScrollPos = window.pageYOffset;

      if (currentScrollPos == 0) {
        this.scrollingUp = false;
        this.scrollingDown = false;
        return;
      }

      if (currentScrollPos < 100) return; // set offset here

      if (this.prevScrollpos > currentScrollPos) {
        // up
        this.scrollingDown = false;
        this.scrollingUp = true;
      } else {
        // down
        this.scrollingUp = false;
        this.scrollingDown = true;
      }

      this.prevScrollpos = currentScrollPos;
    },

    handleScroll() {
      let doScoll;

      window.onscroll = () => {
        clearTimeout(doScoll);
        doScoll = setTimeout(this.scrollNow, 100); // firing less scroll events
      };
    },
  },

  created() {
    this.handleScroll();
  },
};
</script>

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.