Home > Enterprise >  How to disable scroll in mobile menu in vue?
How to disable scroll in mobile menu in vue?

Time:01-20

So basically the toggle for the menu is the checkbox with the id "check" down below. I've tried binding v-bind: to the body in html but it didn't work. The same when I tried it in the main App.vue. But it worked when I put it in the nav on the same .vue page. How do I make it work in the body or main vue app? The condition is when the screen is smaller than 1300 width and checkboxValue true then antiscroll class will be bound.

navigationbar.vue
<template>
  <nav> <!-- The header menu or navigation bar -->
    <input type="checkbox" id="check" v-model="checkboxValue"> <!-- The three stripe icon for the drop down menu, note: drop down menu only works in smaller screen -->
    <label for="check" >
      <i ></i>
    </label>
    <label > <!-- The logo and website name -->
      <router-link to="/" @click="uncheck">
        <img  src="#">
        <font  face="Arial" style="float: left; margin-left: 10px; margin-right: 100px">Test</font>
      </router-link>
    </label>
    <ul> <!-- The menu contains href links to other pages -->
      <li>
        <router-link to="/" @click="uncheck"><b>Home</b></router-link>
      </li>
      <li>
        <router-link to="/catalog" @click="uncheck"><b>Catalog</b></router-link>
      </li>
      <li>
        <router-link to="/about" @click="uncheck"><b>About</b></router-link>
      </li>
      <li> <!-- The search bar -->
      <input type="search" placeholder="Search"  onchange="Search()" id="search">
      </li>
    </ul>
  </nav>
</template>

<script>
export default {
  name: 'navigationbar',
  data () {
    return {
      checkboxValue: false
    }
  },
  methods: {
    uncheck () {
      this.checkboxValue = false
    }
  }
}
</script>

App.vue
<template>
  <div>
    <navigationbar/>
    <router-view v-slot="{ Component }">
      <transition name="fade" mode="out-in">
      <component :is="Component" />
      </transition>
    </router-view>
  </div>
</template>

<script>
import navigationbar from './components/navigationbar.vue'

export default {
  name: 'App',
  components: {
    navigationbar
  }
}
</script>

<style>
*{
  padding: 0;
  margin: 0;
  text-decoration: none;
  list-style: none;
  box-sizing: border-box;
}
body{
  font-family: montserrat;
  background: #c5d5cb;
}
nav{
  height: 80px;
}
nav ul{
  float: right;
  margin-right: 20px;
}
nav ul li{
  display: inline-block;
  line-height: 80px;
  margin: 0 5px;
}
nav ul li a{
  color:rgb(22, 22, 22);
  font-size: 17px;
  padding: 7px 13px;
  border-radius: 3px;
  text-transform: uppercase;
}
a.router-link-exact-active,a:hover{ /* Changes background color of a button when hovered */
  background: #e9ffe9;
  transition: .5s;
}
.checkbtn{
  font-size: 30px;
  color: rgb(22, 22, 22);
  float: right;
  line-height: 80px;
  margin-right: 40px;
  cursor: pointer;
}
#check{
  display: none;
}
@media (max-width: 850px){ /* The @media adjust the components when the screen's size reached as low as the value */
  .logoname{
    font-size: 32px;
  }
  .logoimage{
    width: 56px;
  }
  nav ul li a{
    font-size: 16px
  }
}
@media (max-width: 450px){
  .logoname{
    display: none;
  }
}
@media (max-width: 1300px){
  .checkbtn{
    display: block;
  }
  nav ul{
    position: fixed;
    width: 100%;
    height: 100vh;
    background: #455462;
    top: 80px;
    left: -100%;
    text-align: center;
    transition: all .5s;
  }
  nav ul li{
    display: block;
    margin: 50px 0;
    line-height: 30px;
  }
  nav ul li a{
    font-size: 20px;
  }
  a.router-link-exact-active,a:hover{ /* Changes background color of a button when hovered */
    background: #e9ffe9;
    color: #455462;
  }
  #check:checked ~ ul{
    left: 0;
  }
  .fade-enter-active, .fade-leave-active {
    transition: none !important;
  }
  .fade-enter-from, .fade-leave-to {
    transition: none !important;
  }
}
.antiscroll {
  position: fixed;
}
</style>

index.html
<body v-bind:>
  <div id="app"></div>
</body>

CodePudding user response:

It's much easier with vue, declare a variable (I used overflowCondition as variable name, you can use whatever) that you could use to determine whether the state of the button was clicked or not, put that on your data, then give a v-if condition on the class to either use this style or not. Check the code below for your reference.

<button @click="this.overflowCondition = !this.overflowCondition"> <!-- The three stripe icon for the drop down menu, note: drop down menu only works in smaller screen -->
  <label for="check" >
  <i ></i>
  </label>
</button>
<div :style="this.overflowCondition == true ? 'overflow:hidden'; ''"> //Whatever container you intend to disable it's scroll-ability.

More on overflow property here.

CodePudding user response:

You cannot bind like you want to bind in the index.html like you have it. If you need to manipulate the class of the body tag you will need to access it directly.

Try this:

<template>
  <div>  
    <button  @click="expandMenu">
      <i ></i>
    </button>
  </div>
</template>

<script>
export default {
  methods: {
    expandMenu() {
      this.menuExpanded = !this.menuExpanded;
      
      if (this.menuExpanded) {
        document.body.classList.add("disableScroll");
      } else {
        document.body.classList.remove("disableScroll");
      }
    }
  },
  data() {
    return {
      menuExpanded: false,
    }
  }
}
</script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>

  •  Tags:  
  • Related