How can I prevent scrolling in a Vue mobile menu?

In this scenario, the toggle for the menu is controlled by a checkbox with the id "check" below. I attempted to bind v-bind:class="[{'antiscroll': checkboxValue}]" to the body in HTML, and also in the main App.vue file, but it did not work as expected. However, it worked when I placed it within the navigation bar on the same .vue page. How can I implement this functionality in the body or the main vue app? The requirement is that when the screen width is less than 1300 pixels and checkboxValue is set to true, the antiscroll class should be applied.

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" class="checkbtn">
      <i class="fas fa-bars"></i>
    </label>
    <label class="logo"> <!-- The logo and website name -->
      <router-link to="/" @click="uncheck">
        <img class="logoimage" src="#">
        <font class="logoname" 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" class="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:class="[{ 'antiscroll': checkboxValue }]">
  <div id="app"></div>
</body>

Answer №1

To simplify things using vue, create a variable (such as overflowCondition) to track the button's click state. Add this variable to your data and use a v-if condition on the class to apply a style based on its value. See the code snippet below for an example.

<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" class="checkbtn">
    <i class="fas fa-bars"></i>
  </label>
</button>
<div :style="this.overflowCondition == true ? 'overflow:hidden'; ''"> //Container with scroll-ability disabling.

Learn more about the overflow property here.

Answer №2

If you want to bind in the index.html file, keep in mind that you can't do it as easily as you might think. To manipulate the body tag's class, you'll need to access it directly.

Here's an example:

<template>
  <div>  
    <button class="menu" @click="expandMenu">
      <i class="fas fa-bars"></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>

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Customized figcaption formatting separate from the surrounding text

Is there a way to add a "figcaption" with independent settings to images placed alongside paragraphs in HTML? I have the following code snippet, but I'm unsure if I am using the figcaption tag correctly: <p><figure><span class="image ...

What is preventing me from displaying an AJAX JSON value on my website?

Below is the code snippet: <ul> <li v-for="value in RandomTopic" :key="value.id">{{ value.title }}</li> </ul> export default { data() { return { RandomTopic: null } }, mounted() { ///so ...

Words fail to display

.sport { content: url("../img/sport.png"); background-color: rgba(0,0,0,1.0); top: 61px; height: 310px; width: 300px; position: absolute; margin: 0; left: 0; border-radius: 4px; overflow: hidden; } .sportsandactivis { background-colo ...

Using Vue.js 3 to fetch data from a REST API using the Axios

How do I properly retrieve and display an array using axios.get in Vue? The data is not showing up in my table cells when I use the v-for directive. Could the issue be related to the v-for statement? <tr v-for="params in form" :key=" ...

What is the best way to transfer a user-generated PNG file to my backend server?

I'm in the process of developing a website that enables users to generate personalized graphics and easily download them directly from the platform. My approach involves allowing users to customize an svg using a javascript-powered form, which is the ...

How to position collapsible buttons in Twitter's Bootstrap framework

I have successfully created two buttons on the same line. The second button is collapsible and when clicked, it adds a row of two more buttons to the view. However, the newly collapsed row of buttons appears aligned with the second button. I would like th ...

Using JavaScript to ensure that a div is not hidden on page load if a checkbox is unchecked

Upon inspecting a page, I am implementing a script to check if a checkbox is selected. If not selected, the goal is to hide a specific div element. While troubleshooting this issue, I suspect the problem may be due to the lack of an inline element within t ...

What is the method for retrieving the active element with Waypoint?

Currently, I am implementing Waypoint (version 7.3.2) in my React project using React version 16. My goal is to create a scrollable list of items where each item fades out as it reaches the top of the container div. My main inquiry is how can I obtain a re ...

Encountering a Problem with vue-check-view Library in Typescript

After successfully declaring the js plugin with *.d.ts, I encountered an issue where my view was blank after using .use(checkView). Does the library vue-check-view support Typescript? Error: Uncaught TypeError: Cannot read property '$isServer' o ...

Having difficulty retrieving POST request information from an HTML form using Flask

I have been experimenting with building a website back-end using the Python library Flask. However, I keep encountering a 405 - Method not allowed error whenever I attempt to retrieve form data from a POST request in a secure manner. Right now, after a use ...

Data within object not recognized by TableCell Material UI element

I am currently facing an issue where the content of an object is not being displayed within the Material UI component TableCell. Interestingly, I have used the same approach with the Title component and it shows the content without any problems. function ...

Creating multi-dimensional arrays using array lists with Axios and Vue.js

My knowledge of axios and JavaScript is limited, and I find myself struggling with creating a multi-dimensional array. 1. This is how I want my data to be structured : https://i.stack.imgur.com/kboNU.png userList: [ { ...

HTML set hover & active states to remain active indefinitely

NOTE: My project utilizes Angular, so Angular may offer a solution to this issue as well I am in the process of creating a page where I can preview and test out various styles that I have designed. In order to achieve this, I need to somehow activate both ...

Maximizing the potential of Vue with brunch

I'm having issues while attempting to integrate Vue with Django using brunch. Whenever I try to debug my JavaScript code, I notice that it fails at the following line: import Vue from 'vue/dist/vue.js' The error message displayed is ' ...

What is the best way to substitute unpredictable dynamic variables on-the-fly?

I am working with a .js file that contains a config structure similar to this: genGetLocations:{ data_url:'restaurants/{var1}/tables/{var2}, } This is just one example. Some configurations may have data_url with more than two dynamic variables. I ...

Adjust the PHP variable's value when loading content via AJAX

Seeking assistance after attempting to create a PHP template within the Foundation 4 framework without clear guidance. The framework is quite basic, so I used jQuery to incorporate page transitions by making an AJAX call to retrieve "content" from another ...

Spring load without CSS

Upon successful login, I am redirected to my main site using the following controller: //Login Success @GetMapping("/login-success") public ModelAndView loginSuccess() { return new ModelAndView("/cont/home.html"); } The URL for this redirection i ...

What strategies does Wired magazine use to create their unique thick underline link style?

Recently, I came across an interesting design choice on Wired magazine's website - they use a thick blue underline for their links that crosses over text descenders and is a different color from the text itself. You can see an example on this random p ...

Designing personalized sass components

Seeking advice on developing a custom CSS unit that can be utilized in Sass with Node.js. Is there a tutorial available for creating a Sass plugin specifically for this purpose? For instance, I am looking to establish a unit called "dpx" which functions as ...

Develop interactive web applications using Typescript

Having difficulty compiling and executing the project correctly in the browser. The "master" branch works fine, but I'm currently working on the "develop" branch. It's a basic web project with one HTML file loading one TS/JS file that includes i ...