Adjust the menu scrollbar position to the right or limit scrolling to within the menu area

$(function() {
  "use strict";
  $(".navbar-toggler").on("click", function() {
    $(".navbar-toggler").toggleClass("collapsed");
    $(".offcanvas-collapse").toggleClass("open");
    let menuposition = $("#toggler").offset().left + $("#toggler").width() + 55;
    let windowsize = $(window).width();
    let offcanvas = windowsize - menuposition;
    let fromtop = $("#navigation").height() + 16;
    $(".offcanvas-collapse").css("right", offcanvas);
    $(".offcanvas-collapse").css("top", fromtop);
    $("body").toggleClass("off-canvas-active");
    if (!$(".navbar-brand").hasClass("makeappear")) {
      $(".navbar-brand").addClass("makeappear");
    }
    if ($("body").hasClass("off-canvas-active")) {
      $("html").addClass("no-scroll");
    } else {
      $("html").removeClass("no-scroll");
    }
  });

  $(".off-canvas-overlay").on("click", function() {
    $(".navbar-toggler").toggleClass("collapsed");
    $(".offcanvas-collapse").toggleClass("open");
    $("body").toggleClass("off-canvas-active");
    if ($("body").hasClass("off-canvas-active")) {
      $("body").addClass("nav-open");
    } else {
      $("body").removeClass("nav-open");
    }
    if ($("body").hasClass("off-canvas-active")) {
      $("html").addClass("no-scroll");
    } else {
      $("html").removeClass("no-scroll");
    }
  });



  
});
.navbar-nav li .nav-link {
  padding-right: .5rem;
  padding-left: .5rem;
}
#navbarCollapse li.active {
  background-color: #BA122B;
}
#navbarCollapse li.active a {
  color: #FFF;
  background-color: #BA122B;
}

#navbarCollapse .menu {
  padding-top: 30px;
}
#navbarCollapse .dropdown-menu {
  padding-left: 20px;
}
#navbarCollapse li a {
  border-bottom: 1px solid #E3E3E3;
  color: #BA122B;
  -webkit-transition-duration: 0.3s;
  transition-duration: 0.3s;
  -webkit-transition-property: color, background-color;
  transition-property: color, background-color;
  -webkit-transform: perspective(1px) translateZ(0);
  transform: perspective(1px) translateZ(0);
}
#navbarCollapse li a:hover {
  color: #FFF;
  background-color: #BA122B;
}
#navbarCollapse parent:after {

}
.body {
  background-color: #f6f6f6;
  padding-top: 2rem;
}

.off-canvas-active .off-canvas-overlay {
  opacity: 1;
  visibility: visible;
}
.off-canvas-overlay {
  position: fixed;
  right: 0;
  top: 0;
  width: 100%;
  height: 100%;
  background-color: rgba(0, 0, 0, .75);
  z-index: 1000;
  visibility: hidden;
  opacity: 0;
  transition: .3s ease-in-out;
 
}
.offcanvas-collapse.open {

  display: block;
  -webkit-animation: slide-right .3s ease-out;
    -moz-animation: slide-right .3s ease-out;
}
@-webkit-keyframes slide-right {
      0% { opacity: 0; -webkit-transform: translateX(-100%); }
    100% { opacity: 1; -webkit-transform: translateX(0); }
}
@-moz-keyframes slide-right {
      0% { opacity: 0; -moz-transform: translateX(-100%); }
    100% { opacity: 1; -moz-transform: translateX(0); }
}
.offcanvas-collapse {
  position: fixed;
  top: 56px;
  bottom: 0;
  right: 0;
  width: 270px;
  transition-timing-function: ease-in-out;
  transition-duration: .3s;
  transition-property: width;
  display: none;
  overflow-y:auto;
}
.navbar-expand-md .navbar-toggler {
  display: block!important;
}

.navbar-toggler {
  border: none;
  height: 40px;
}
.navbar-toggler:active, .navbar-toggler:focus {
  outline: 0;
}
.navbar-toggler .icon-bar {
  display: block;
  width: 30px;
  height: 2px;
  border-radius: 1px;
  transition: .3s ease-in-out;
  background-color: #BA122B;
}
.navbar-dark .navbar-toggler .icon-bar {
  background: #ffffff;
}
.navbar-toggler .icon-bar:nth-of-type(1) {
  transform: rotate(45deg) translate(2px, 2px);
}
.navbar-toggler .icon-bar:nth-of-type(2) {
  opacity: 0;
}
.navbar-toggler .icon-bar:nth-of-type(3) {
  transform: rotate(-45deg) translate(1px, -1px);
}
.navbar-toggler.collapsed .icon-bar {
  margin: 5px auto;
  transform: none;
  opacity: 1;
}
.navbar-nav .dropdown-menu {
  padding: 0;
  border: none;
  margin: 0;
  border-radius: 0;
}
.dropdown-toggle::after {
  right: 30px;
  position: absolute;
  top: 50%;
}
.nav-open {
    overflow: hidden;
}
.no-scroll {
  position: fixed;
  width: 100%;
  height: 100%;
  overflow-y: scroll;
}
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js" integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script>
</head>
<body class="site">
<nav id="navigation" class="navbar fixed-top navbar-white bg-white border-bottom shadow-sm">
      <div class="container">
        <a class="navbar-brand" href="#">
        </a>
        <button id="toggler" class="navbar-toggler collapsed" type="button" data-toggle="offcanvas" data-target="#navbarCollapse" aria-controls="navbarCollapse" aria-expanded="false" aria-label="Toggle navigation">
          <span class="icon-bar"></span>
          <span class="icon-bar"></span>
          <span class="icon-bar"></span>
        </button>
        <div class="offcanvas-collapse border-left shadow-sm bg-white" id="navbarCollapse">
          <ul class="nav menu navbar-nav ml-auto text-uppercase mod-list">
<li class="item-102 default current active"><a href="/demo/" class=" nav-link">Welcome!</a></li><li class="item-103 deeper parent dropdown"><a href="#" title="#pageSubmenu" class="nav-link dropdown-toggle" data-toggle="dropdown" aria-expanded="false" "="">testing</a><ul class="nav-child unstyled small dropdown-menu"><li class="item-110"><a href="#" class="nav-link">level 2</a></li></ul></li><li class="item-104 deeper parent dropdown"><a href="/demo/aasssssssssssssssssssssss-2" class="nav-link dropdown-toggle" data-toggle="dropdown" aria-expanded="false" "="">testing</a><ul class="nav-child unstyled small dropdown-menu"><li class="item-111"><a href="#" class="nav-link">level 3</a></li></ul></li><li class="item-105"><a href="#" class="nav-link">testing</a></li><li class="item-106"><a href="#" class="nav-link">testing</a></li><li class="item-107"><a href="#" class="nav-link">testing</a></li><li class="item-108"><a href="#" class="nav-link">testing</a></li><li class="item-109"><a href="#" class="nav-link">testing</a></li><li class="item-102 default current active"><a href="/demo/" class=" nav-link">Welcome!</a></li><li class="item-103 deeper parent dropdown"><a href="#" title="#pageSubmenu" class="nav-link dropdown-toggle" data-toggle="dropdown" aria-expanded="false" "="">testing</a><ul class="nav-child unstyled small dropdown-menu"><li class="item-110"><a href="#" class="nav-link">level 2</a></li></ul></li><li class="item-104 deeper parent dropdown"><a href="/demo/aasssssssssssssssssssssss-2" class="nav-link dropdown-toggle" data-toggle="dropdown" aria-expanded="false" "="">testing</a><ul class="nav-child unstyled small dropdown-menu"><li class="item-111"><a href="#" class="nav-link">level 3</a></li></ul></li><li class="item-105"><a href="#" class="nav-link">testing</a></li><li class="item-106"><a href="#" class="nav-link">testing</a></li><li class="item-107"><a href="#" class="nav-link">testing</a></li><li class="item-108"><a href="#" class="nav-link">testing</a></li><li class="item-109"><a href="#" class="nav-link">testing</a></li><li class="item-102 default current active"><a href="/demo/" class=" nav-link">Welcome!</a></li><li class="item-103 deeper parent dropdown"><a href="#" title="#pageSubmenu" class="nav-link dropdown-toggle" data-toggle="dropdown" aria-expanded="false" "="">testing</a><ul class="nav-child unstyled small dropdown-menu"><li class="item-110"><a href="#" class="nav-link">level 2</a></li></ul></li><li class="item-104 deeper parent dropdown"><a href="/demo/aasssssssssssssssssssssss-2" class="nav-link dropdown-toggle" data-toggle="dropdown" aria-expanded="false" "="">testing</a><ul class="nav-child unstyled small dropdown-menu"><li class="item-111"><a href="#" class="nav-link">level 3</a></li></ul></li><li class="item-105"><a href="#" class="nav-link">testing</a></li><li class="item-106"><a href="#" class="nav-link">testing</a></li><li class="item-107"><a href="#" class="nav-link">testing</a></li><li class="item-108"><a href="#" class="nav-link">testing</a></li><li class="item-109"><a href="#" class="nav-link">testing</a></li><li class="item-102 default current active"><a href="/demo/" class=" nav-link">Welcome!</a></li><li class="item-103 deeper parent dropdown"><a href="#" title="#pageSubmenu" class="nav-link dropdown-toggle" data-toggle="dropdown" aria-expanded="false" "="">testing</a><ul class="nav-child unstyled small dropdown-menu"><li class="item-110"><a href="#" class="nav-link">level 2</a></li></ul></li><li class="item-104 deeper parent dropdown"><a href="/demo/aasssssssssssssssssssssss-2" class="nav-link dropdown-toggle" data-toggle="dropdown" aria-expanded="false" "="">testing</a><ul class="nav-child unstyled small dropdown-menu"><li class="item-111"><a href="#" class="nav-link">level 3</a></li></ul></li><li class="item-105"><a href="#" class="nav-link">testing</a></li><li class="item-106"><a href="#" class="nav-link">testing</a></li><li class="item-107"><a href="#" class="nav-link">testing</a></li><li class="item-108"><a href="#" class="nav-link">testing</a></li><li class="item-109"><a href="#" class="nav-link">testing</a></li></ul>
        </div>
      </div>
    </nav>
<div class="off-canvas-overlay"></div>
</body>
</html>

I have implemented an offcanvas menu that activates upon clicking. I am looking to restrict body/html scrolling when the menu is open and allow scrolling within the menu itself.

In the screenshot provided, I managed to disable scrolling on the body/html and enable scrolling within the menu area. Is it possible to move the scrollbar to the right as shown in the illustration?

Alternatively, is there a way using JavaScript/jQuery to prevent scrolling on the body while enabling scrolling specifically for the menu?

If you have any alternative suggestions on achieving this functionality, please feel free to share :)

https://i.sstatic.net/JXror.png

Answer №1

It seems that the example you provided was very close to working correctly, but there was a small CSS error related to scrolling that needed fixing.

Your JavaScript code successfully added the no-scroll class to the html element. However, the CSS for the .no-scroll class had the property overflow-y set to scroll instead of hidden. Setting it to

hidden</code ensures that the scrollbar is hidden when content exceeds the height of the element.</p>
<p>If my understanding is incorrect or if you have any further questions about the changes I made, please let me know.</p>
<p><div>
<div>
<pre class="lang-js"><code>$(function() {
  "use strict";
  // Your JavaScript code here
});
.your-css-rules-here {
  /* Your CSS rules */
}
<!DOCTYPE html>
<html lang="en">
<head>
  <link rel="stylesheet" href="[your-stylesheet-url]">
  <script src="[your-javascript-url]"></script>
</head>
<body>
  <!-- Your HTML content here -->
</body>
</html>

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

Adaptable positioned picture

I'm trying to figure out how to make a series of positioned images adjust to the window's dimensions. Should the images be relative and the page wrap absolute, or vice versa? I've been experimenting on jsfiddle but can't seem to get it ...

Utilizing ngRepeat to build intricate rows within a table

I have a unique collection that appears as follows: { "10": {}, "12": { "20": { "value": 1, "id": 1, }, "100": { "value": 12, "id": 1, } }, "14": { "10 ...

The debate between client-side and server-side video encoding

My knowledge on this topic is quite limited and my Google search didn't provide any clear answers. While reading through this article, the author mentions: In most video workflows, there is usually a transcoding server or serverless cloud function ...

Cut off the initial characters in the URL's hash component

Hey there, I'm currently working on a task that involves removing a specific part of a URL string. Here's the scenario: if (window.location.hash == '#super-super-product') { change.window.location.hash.to.this: #product // this i ...

What is the best method for integrating jQuery FullCalendar using AJAX?

I need assistance loading a full calendar using Ajax. The data will be passed from the controller in JSON format, but I am unsure of how to implement it. Can someone please help me with this? Here is my controller code: public function calenderHoliday(){ ...

Fetch information that was transmitted through an ajax post submission

How can I retrieve JSON formatted data sent using an ajax post request if the keys and number of objects are unknown when using $_POST["name"];? I am currently working on a website that functions as a simple online store where customers can choose items m ...

What is causing the 'info' object to be undefined?

transporter.sendMail(mailOptions,(error,info)=>{ if(error) console.log(error) console.log('Message Sent: '+info.messageId) console.log('Preview URL: '+nodemailer.getTestMessageUrl(info)) res.redirect('contacts', ...

What are some strategies for optimizing React performance when managing controlled input from numerous components?

Building a Parent component with multiple child components, each passing data to the parent for an API call. The structure is as follows: const MainComponent = () => { const [child1input, setChild1Input] = useState(""); const [child2input, setChild ...

Extracting information from a database (HTML, JavaScript)

I am currently working on a table that receives data from the server using ajax: $.each(data, function(i, item) { $('#MyTable tbody').append("<tr>" +"<td>" +data[i].A+ "</td><td>" +d ...

What is the best way to organize two separate arrays based on a single shared variable?

I have two separate arrays containing information. One array includes the title of each national park and other related data, while the second array consists of alerts from the entire NPS system. The common factor between these arrays is the parkCode. How ...

Error encountered: `npm ERR! code E503`

While attempting to execute npm install on my project, which was cloned from my GitHub repository, I encountered the following error: npm ERR! code E503 npm ERR! 503 Maximum threads for service reached: fs-extra@https://registry.npmjs.org/fs-extra/-/fs-ex ...

What is a way to retain the value of a variable after a request, while starting off with a different value on the initial load?

In my Flask application, users have the option to choose a specific time period with a start date and an end date. When the page initially loads, I want the start date to default to the first day of the current month and the end date to be the current day. ...

Error in Angular 4: Undefined property 'replace' causing trouble

I've been trying to use the .replace() JavaScript function in Angular 4 to remove certain characters from a string. Here is the code snippet from my component: @Component({...}) export class SomeComponent implements OnInit { routerUrl: string = &apo ...

how to name a collection variable in MongoDB shell using JavaScript

When using the mongo shell with JavaScript, is it possible to dynamically set the collection name in order to work with multiple collections? db.collection.insert() ...

Special effects for the images动画效果。

Is there a way to add animation effects to images in the about section using this code: <div id="about" class="row section bgimg3"> <div class="col-sm-8"> <h2 style="color:black;">Want to Know More About me?</h2> ...

Why is it that I am not receiving JSON data in my Angular application?

I am currently working on a class within a webapi public class ResponseObject { public int Success { get; set; } public string Message { get; set; } public object Data { get; set; } } Within my ASP.NetCore, I have the following method: publi ...

Animate the background of a table cell (td) in React whenever a prop is updated

I have a dynamic table that receives data from props. I would like the background animation of each cell (td) to change every time it receives new props. I've tried creating an animation for the background to indicate when a cell is updated, but it on ...

Display the input text value when the button is clicked

I am a beginner in JavaScript and have created this HTML page: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8> <title>Document</title> Upon entering text into the input field and clicking on the submi ...

What is the most effective way to transfer information between two pages in React JS?

I am a newcomer to react and currently working on a project that involves two pages/components. I collect user details on one page and need to display that data on another page. However, I am facing difficulties in achieving this. Can someone please provid ...

The specified method is not recognized as a function in the ReactJS library

Within my reactJS application, there is a function that calls upon a helper function to retrieve the result of a calculation. The component looks like this: import React, { Component } from "react"; import * as d3 from "d3"; class DrawImage extends Comp ...