How can I use jQuery to prevent the page from scrolling to the top and lock the scrollbar?

When triggering the overlay, I successfully lock the scrollbar on the window. However, an issue arises when scrolling to the bottom or middle of the page and activating the overlay - the body/document jumps to the top.

I aim for a behavior similar to Facebook's image overlay/popup where the background remains locked when clicking on an image but returns to normal after exiting the popup. Is this achievable?

CSS:

html,
body {
  font-family: 'Raleway', sans-serif;
  height: auto;
  margin: 0;
  padding: 0;
  overflow: auto;
  color: #000;
}

html.lock-scrollbar {
  position: fixed;
  overflow-y: scroll;
  width: 100%;
  height: 100%;
}

#main {
    height: 2000px;
    border: 1px solid red;
}

.overlay {
    width: 90%;
    height: 100%;
    background: #fff;
    z-index: 999;
    overflow: auto;
    position: absolute;
    top: 0;
    left: 0;
    display: none;
    border: 1px solid black;
} 

jQuery:

 $( document ).ready(function() {
    var windowHeight = $(window).height();
    console.log(windowHeight);

    $("#main").click(function(){
        $("html").addClass('lock-scrollbar');
        $('.overlay').show();
        return false;
    });

    $(".overlay").click(function(){
        $("html").removeClass('lock-scrollbar');
        $('.overlay').hide();
        return false;
    });
});

HTML:

 <div id="main">
    <h1>New Scrolling Window</h1>
    <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Etiam a justo erat, volutpat hendrerit dolor. Sed urna nibh, dapibus at egestas non, vulputate ut quam. Morbi a erat tristique tellus varius venenatis. Aenean lacinia sem eget turpis fringilla commodo. Sed lorem nisi, viverra a interdum nec, varius eu enim. Donec ornare, nunc quis eleifend iaculis, nulla eros mollis tellus, quis faucibus risus odio non lectus. Maecenas ac velit non metus rhoncus commodo. Nunc ligula est, ultricies sed mattis sed, dapibus at arcu. Maecenas lacinia nisl ut sem bibendum ac condimentum purus facilisis. Curabitur ut nibh lobortis libero interdum vehicula vel quis nulla.</p>

    <p>Suspendisse et massa urna. Donec eu lorem nec felis dapibus aliquam viverra in quam. Suspendisse ultrices, nisi ac venenatis porttitor, erat turpis dapibus augue, sed rutrum nunc ante sed enim. Aliquam et tempus mi. Nullam malesuada, nunc a eleifend pretium, justo lorem tempus justo, id adipiscing dolor ipsum sed velit. Maecenas odio massa, feugiat vel sodales ut, placerat at quam. Cras viverra diam vitae diam elementum vitae aliquet erat tincidunt. Quisque fringilla neque in lacus tempor cursus. Curabitur eget nulla et nisi dignissim tempor vel non risus. Mauris ac ipsum metus, a auctor massa. Nunc eros ante, ullamcorper a mollis nec, aliquam sed est. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas.</p>
</div>
<div class="overlay"></div>

What could be my mistake?

Here is the link to my jsfiddle.

Answer №1

In my approach, instead of using a fixed positioned lock-scrollbar, I prefer to manage the scroll in this way:

$('html,body').css({'overflow-y': 'hidden'});

Upon clicking on main, I revert overflow-y back to auto:

$('html,body').css({'overflow-y': 'auto'});

When the overlay is hidden.

For a demonstration and an updated fiddle, check out this link:

$(document).ready(function() {
  var windowHeight = $(window).height();
  // console.log(windowHeight);

  $("#main").click(function() {
    $('html,body').css({'overflow-y': 'hidden'});
    $('.overlay').show();
    return false;
  });

  $(".overlay").click(function() {
    $('html,body').css({'overflow-y': 'auto'});
    $('.overlay').hide();
    return false;
  });
});
html,
body {
  font-family: 'Raleway', sans-serif;
  height: auto;
  margin: 0;
  padding: 0;
  overflow: auto;
  color: #000;
}
html.lock-scrollbar {
  position: fixed;
  overflow-y: scroll;
  width: 100%;
  height: 100%;
}
#main {
  height: 2000px;
  border: 1px solid red;
}
.overlay {
  width: 90%;
  height: 100%;
  background: #fff;
  z-index: 999;
  overflow: auto;
  position: fixed;
  top: 0;
  left: 0;
  display: none;
  border: 1px solid black;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<div id="main">
  <h1>New Scrolling Window</h1>
  <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Etiam a justo erat, volutpat hendrerit dolor. Sed urna nibh, dapibus at egestas non, vulputate ut quam. Morbi a erat tristique tellus varius venenatis. Aenean lacinia sem eget turpis fringilla
    commodo. Sed lorem nisi, viverra a interdum nec, varius eu enim. Donec ornare, nunc quis eleifend iaculis, nulla eros mollis tellus, quis faucibus risus odio non lectus. Maecenas ac velit non metus rhoncus commodo. Nunc ligula est, ultricies sed mattis
    sed, dapibus at arcu. Maecenas lacinia nisl ut sem bibendum ac condimentum purus facilisis. Curabitur ut nibh lobortis libero interdum vehicula vel quis nulla.</p>

  <p>Suspendisse et massa urna. Donec eu lorem nec felis dapibus aliquam viverra in quam. Suspendisse ultrices, nisi ac venenatis porttitor, erat turpis dapibus augue, sed rutrum nunc ante sed enim. Aliquam et tempus mi. Nullam malesuada, nunc a eleifend
    pretium, justo lorem tempus justo, id adipiscing dolor ipsum sed velit. Maecenas odio massa, feugiat vel sodales ut, placerat at quam. Cras viverra diam vitae diam elementum vitae aliquet erat tincidunt. Quisque fringilla neque in lacus tempor cursus.
    Curabitur eget nulla et nisi dignissim tempor vel non risus. Mauris ac ipsum metus, a auctor massa. Nunc eros ante, ullamcorper a mollis nec, aliquam sed est. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas.</p>
</div>
<div class="overlay"></div>

EDIT:

If you prefer the position: fixed solution - manipulate the scrollTop value to reset the scroll.

I also included

$('html').css({'top':-scrollTop + 'px'})
while locking the scroll - view the demo below:

$(document).ready(function() {
  var windowHeight = $(window).height();
  // console.log(windowHeight);
  var scrollTop = 0;

  $("#main").click(function() {
    scrollTop = $(window).scrollTop();
    $("html").addClass('lock-scrollbar');
    $('html').css({'top':-scrollTop + 'px'});
    $('.overlay').show();
    return false;
  });

  $(".overlay").click(function() {
    $("html").removeClass('lock-scrollbar');
    $(window).scrollTop(scrollTop);
    $('.overlay').hide();
    return false;
  });
});
html,
body {
  font-family: 'Raleway', sans-serif;
  height: auto;
  margin: 0;
  padding: 0;
  color: #000;
}
html.lock-scrollbar {
  position: fixed;
  overflow-y: scroll;
  width: 100%;
  height: 100%;
}
#main {
  height: 2000px;
  border: 1px solid red;
}
.overlay {
  width: 90%;
  height: 100%;
  background: #fff;
  z-index: 999;
  overflow: auto;
  position: fixed;
  top: 0;
  left: 0;
  display: none;
  border: 1px solid black;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js""></script>

<div id="main">
  <h1>New Scrolling Window</h1>
  <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Etiam a justo erat, volutpat hendrerit dolor. Sed urna nibh, dapibus at egestas non, vulputate ut quam. Morbi a erat tristique tellus varius venenatis. Aenean lacinia sem eget turpis fringilla
    commodo. Sed lorem nisi, viverra a interdum nec, varius eu enim. Donec ornare, nunc quis eleifend iaculis, nulla eros mollis tellus, quis faucibus risus odio non lectus. Maecenas ac velit non metus rhoncus commodo. Nunc ligula est, ultricies sed mattis
    sed, dapibus at arcu. Maecenas lacinia nisl ut sem bibendum ac condimentum purus facilisis. Curabitur ut nibh lobortis libero interdum vehicula vel quis nulla.</p>

  <p>Suspendisse et massa urna. Donec eu lorem nec felis dapibus aliquam viverra in quam. Suspendisse ultrices, nisi ac venenatis porttitor, erat turpis dapibus augue, sed rutrum nunc ante sed enim. Aliquam et tempus mi. Nullam malesuada, nunc a eleifend
    pretium, justo lorem tempus justo, id adipiscing dolor ipsum sed velit. Maecenas odio massa, feugiat vel sodales ut, placerat at quam. Cras viverra diam vitae diam elementum vitae aliquet erat tincidunt. Quisque fringilla neque in lacus tempor cursus.
    Curabitur eget nulla et nisi dignissim tempor vel non risus. Mauris ac ipsum metus, a auctor massa. Nunc eros ante, ullamcorper a mollis nec, aliquam sed est. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas.</p>
</div>
<div class="overlay"></div>

Answer №2

Consider using CSS:

html, body {
  font-family: 'Raleway', sans-serif;
  margin: 0;
  padding: 0;
  color: #000;
}

Explore JavaScript as well:

 $( document ).ready(function() {
  var windowHeight = $(window).height();
  console.log(windowHeight);

  $("#main").click(function(){
    $('body').css({
      overflow: 'hidden',
      height: '100%'
            });
    $('.overlay').show();
    return false;
  });

  $(".overlay").click(function(){
    $('body').css({
      overflow: 'auto',
      height: 'auto'
            });
    $('.overlay').hide();
    return false;
  });

});

Here is the updated jsfiddle link: https://jsfiddle.net/y9e1kt3q/

For a version where the scroll remains visible, check out this new fiddle: https://jsfiddle.net/y9e1kt3q/1/

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

Issues with Ajax request (Phonegap, Mysql, PHP) not functioning as intended

I'm in the process of creating a new app with Phonegap, and I've run into an issue on the login page. When I attempt to click the submit button, nothing happens. Here's the code snippet I'm using: index.html <link href="css/sty ...

Use Express JS to enable users to upload their profile picture either during account creation or on the registration form

Just starting out with node js, I'm working on a basic app where users can create accounts with their details. I've implemented mongo dB as the backend to store user information such as names and emails. Once an account is created, users are dir ...

Having trouble getting the material-ui datepicker to function properly

Despite following the installation guide, I'm struggling to make the material-ui datepicker work in React. Each time the datepicker is rendered, it triggers the following error: RangeError: Format string contains an unescaped latin alphabet charact ...

css: Positioning divs relative to their parent div

In my design, I want the blue div to be positioned next to the red div without affecting the yellow div's placement. http://jsfiddle.net/pCGxe/ Is there a cleaner way to achieve this layout without resorting to using position:absolute or other trick ...

Prevent strange appearances when using slideDown animation

In my application, I am experiencing an undesirable side effect when using slideDown(). Upon clicking the element, a piece of content is appended to an ancestor. This causes the clicked button to shift to the right and the ones on the left to move slightly ...

What is the best approach to reverse the selection of <li> elements by utilizing :not() and :contains

I am looking to implement a live search feature using jQuery. Below is the code snippet I have written: $("#searchInput").on("keyup", function () { var searchTerm = $("#searchInput").val(); $('li:contains("' + searchTerm + ' ...

Acquire JSON information from a JSP function for use in a JavaScript file

I am working on a JSP file where I have defined a method that returns JSON data. My goal is to retrieve this JSON data in a JavaScript file using AJAX. However, when I make the AJAX call, instead of getting the JSON data, the entire JSP page is returned. ...

Implementing drag-and-drop functionality for text on an image using javascript

Hey there, I'm looking to develop a super simple meme creator tool. I have some code for adding text to an image and dragging it around. Can anyone help me out? <html> <body> <div id="draggable-element">Drag me!</div> <styl ...

"We are experiencing issues with the app.get function and it is

Although my backend is successfully serving other files, I have encountered an issue with loading new files that are located in a folder named js within the directory. These specific files are not being loaded, and despite spending an hour trying to troubl ...

Creating a horizontal split with HTML's div tag and CSS

Can someone assist me in creating two horizontal divisions using the <div> tag in HTML? I have been struggling to achieve this and would appreciate any help with utilizing HTML and CSS for the task. ...

Error: Trying to access a property "draw" that is not defined and causing a TypeError

for (var i = 0; i < reduced.length; i++) { var innerdata = []; for (var j = 0; j < days.length; j++) { var rev = 0; _.each(reduced[i].data, function(timerevenueObj) { var current = new Date(parseInt(timerevenueObj[0])); ...

Using Javascript, the sum of inputs is calculated based on the keyup event

I am a beginner in javascript and I'm learning about events. Below is the HTML code for a table that displays income titles and their respective prices. <table class="table table-hover table-bordered" id="incomeId"> <thead> <tr&g ...

Tips on updating a div with jQuery AJAX in my PHP script - help needed!

My jQuery call to PHP is functioning well. However, I am trying to figure out if it's possible to directly output the new content of a specific div from the PHP code using the echo statement. Is this achievable? In the past, I would return the update ...

If the ID matches a value in the list, assign a class to the div

Hello, I am looking for assistance on how to add a class to a div if its id matches a value from a predetermined list: list = ["a1", "a2", "a3"] <div id="a1"></div> <div id="b1"></div> <div id="c1"></div> <div id=" ...

Convert an array of objects into a single object with keys from each object in TypeScript

interface Item { slug: string; description: string; } interface Params { id: number; items: Item[]; } function test(params: Params) { const result = {}; for (const item of params.items) { result[item.slug] = "Hello"; } return re ...

Jupyter notebook does not support the visualization of D3 graphics

My code in html/javascript/d3 within jupyter notebook is running without errors, but no circles are being displayed. The expected output should show two circles, one blue and the other green. What could be causing this issue? HTML('<script src="ht ...

The JQuery datepicker is having trouble functioning when used with a masterpage in ASP.NET

Welcome to my Masterpage with the best source code <%@ Page Title="" Language="C#" MasterPageFile="~/Usermaster.Master" AutoEventWireup="true" CodeBehind="ApproveLoanpage.aspx.cs" Inherits="WebLoanCalculator.ApproveLoanpage" %> <%@ Register Asse ...

What is the best way to transfer a variable from a template to views.py?

Is there a way for me to pass the oobcode value to the postresetusername function in views.py? reset_username.html <script type="text/javascript"> var oobcode; function func(){ oobcode = localStorage.getItem("storageName"); ...

Guide to specifying the dimensions of a bar chart on Android devices

I'm currently using phonegap for my app development and incorporating flot to generate charts. Below is the snippet of my JavaScript code: <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <scrip ...

Update the styling for the second list item within a specified unordered list class instantaneously

Looking to emphasize the second list item (li) within a selected dropdown list with a designated unordered list class of "chosen-results". <div class="chosen-container chosen-container-single select-or-other-select form-select required chosen-proc ...