Search code examples
vue.jsvuejs2nuxt.jsbootstrap-vue

Nuxt/Vue/Bootstrap-vue shrink navbar on scroll


Learning Vue with Nuxt. Want to change navbar classes depending on the page scroll position.

Looked in several places, but haven't found a working solution.

Here's what I have to work with:

``` default.vue
<template lang="pug">
div(v-on:scroll="shrinkNav", v-on:click="shrinkNav")
  b-navbar.text-center(toggleable="sm" type="light" sticky v-b-scrollspy)
    #myNav.mx-auto.bg-white
      b-navbar-toggle(target="nav_collapse")
      b-navbar-brand.mx-auto(href="#") 
        | Example.org
      b-collapse#nav_collapse.mx-auto(is-nav='')
        b-navbar-nav(justified, style="min-width: 600px").vertical-center
          b-nav-item.my-auto(href='#home') Home
          b-nav-item.my-auto(href='/how') How
          i.fab.fa-earlybirds.fa-2x.mt-2.mb-3
          b-nav-item.my-auto(href='/values') Values
          b-nav-item.my-auto(href='/join-us') Join Us
  #content.container(v-on:scroll="shrinkNav", v-on:click="shrinkNav")
nuxt
    nuxt
</template>

<script>
  // resize navbar on scroll
  export default {
    methods: {
      shrinkNav() {
        var nav = document.getElementById('nav')
        var content = document.getElementById('content')
        if (nav && content) {
          if(content.scrollTop >= 150) {
            nav.classList.add('shrink')
          } else {
            nav.classList.remove('shrink')
          }
        }
        console.log(document.documentElement.scrollTop || document.body.scrollTop)
      }      
    }
  }
</script>
```

shrinkNav runs twice on click, but nothing on scroll. What is the Vue/Nuxt way to do this?


Solution

  • In your .vue:

    <template> section:

    <nav id="nav" class="navbar is-transparent is-fixed-top">
    

    <script> section:

    export default {
    mounted() {
          this.$nextTick(function(){
            window.addEventListener("scroll", function(){
              var navbar = document.getElementById("nav");
              var nav_classes = navbar.classList;
              if(document.documentElement.scrollTop >= 150) {
                if (nav_classes.contains("shrink") === false) {
                  nav_classes.toggle("shrink");
                }
              }
              else {
                if (nav_classes.contains("shrink") === true) {
                  nav_classes.toggle("shrink");
                }
              }
            })
          })
        },
    }
    

    Live Demo on codesandbox