Press the button to automatically scroll to a designated div section

One of the challenges I'm facing involves a fixed menu and content box (div) on a webpage. Whenever I click on the menu, the content box should scroll to a specific div.

Initially, everything was working fine.

Here is a sample of it in action: https://jsfiddle.net/ezrinn/8cdjsmb9/11/

The issue arises when I try to wrap the entire div setup into a show/hide toggle button - the scrolling functionality stops working.

Here is an example where the scrolling isn't functional: https://jsfiddle.net/ezrinn/8cdjsmb9/10/

Additionally, here is the code snippet:

[JavaScript and jQuery code snippet]
[CSS code snippet]
[HTML code snippet]

If you have any suggestions on how to fix this issue with the code, please provide your input. Thank you for your help.

Answer №1

When you compute the offset, the div is made hidden using display: none. As a result, the offsets are calculated as zero.

To resolve this issue, I quickly put together a solution: https://jsfiddle.net/hrb58zae/

In essence, I restructured the logic to determine the offset after toggling show/hide.

var setOffset = null;

...

if (!setOffset) {
    var scroll_divs = $("." + div_parent_class_name).children();
    id_offset_map.first = 0;
    scroll_divs.each(function(index) {
        id_offset_map["#" + scroll_divs[index].id] = scroll_divs[index].offsetTop
    });
    setOffset = true;
}

Answer №2

To enhance your CSS, consider using visible instead of display: none and display: block:

.wrap { visibility:hidden;}
.wrap.on { visibility:visible;}

By utilizing this approach, you can hide the element without disrupting the layout.

Check out the updated example here: https://jsfiddle.net/a5u683es/

Answer №3

The issue occurred because the attempt was made to update id_offset_map while the content was hidden. When using 'display:none' property, the dimensions for that element are not obtained, which causes it to malfunction.

I have revised the logic, so please review the updated code in this fiddle: https://jsfiddle.net/qfrsmnh5/

var id_offset_map = {};
var div_parent_class_name = "wrap_scroll";
var divs_class = "page-section"; 
var scroll_divs = $("." + div_parent_class_name).children();
   
function updateOffsets(){
    id_offset_map.first = 0;
    scroll_divs.each(function(index) {
        id_offset_map["#" + scroll_divs[index].id] = scroll_divs[index].offsetTop
    });

}

$(document).ready(function() { 

    $('.btn').click(function() {
      $(".wrap").toggleClass('on');
      if($(".wrap").hasClass("on")){
        updateOffsets();
      }
    });

    $('a').on('click', function(e) {
        e.preventDefault();
        var target = $(this).attr("href")
        $('.wrap_scroll').stop().animate({
            scrollTop: id_offset_map[target]
        }, 600, function() {
            /* location.hash = target-20; */ //attach the hash (#jumptarget) to the pageurl
        });

        return false;
    });
});

$(".wrap_scroll").on('scroll',function() {
    var scrollPos = $(".wrap_scroll").scrollTop();
    $("." + divs_class).each(function(i) {
        var divs = $("." + divs_class);

        divs.each(function(idx) {
            if (scrollPos >= id_offset_map["#" + this.id]) {
                $('.menu>ul>li a.active').removeClass('active');
                $('.menu>ul>li a').eq(idx).addClass('active');
            }
            
        }); 
    });
}).scroll();
body,
html {
    margin: 0;
    padding: 0;
    height: 3000px;
}


.wrap { display:none;}
.wrap.on { display:block;}

.menu {
    width: 100px;
    position: fixed;
    top: 40px;
    left: 10px;
}

.menu a.active {
    background: red;
}

.wrap_scroll {
    position: absolute;
    top: 20px;
    left: 150px;
    width: 500px;
    height: 500px;
    overflow-y: scroll;
}

#home {
    background-color: #286090;
    height: 200px;
}

#portfolio {
    background: gray;
    height: 600px;
}

#about {
    background-color: blue;
    height: 800px;
}

#contact {
    background: yellow;
    height: 1000px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button class="btn">show/hide</button> 

<div class="wrap">  
  <div class="menu">
      <ul>
          <li><a class="active" href="#home">Home</a></li>
          <li><a href="#portfolio">Portfolio</a> </li>
          <li><a href="#about">About</a> </li>
          <li><a href="#contact">Contact</a> </li>
      </ul>
  </div> 
  
  <div class="wrap_scroll">
      <div class="page-section" id="home">hh</div>
      <div class="page-section" id="portfolio">pp</div>
      <div class="page-section" id="about">aa</div>
      <div class="page-section" id="contact">cc</div>
  </div>

</div>

Answer №4

It functions perfectly, but the issue arises when using display: none because the element is not rendered which hinders offsetTop calculations. I am uncertain whether all values return 0 or undefined; I assume it's undefined. One solution is to always calculate positions using a specific function:

var div_parent_class_name;
var divs_class;
var id_offset_map = {};
function calcTops(){
    div_parent_class_name = "wrap_scroll";
    divs_class = "page-section"; 
    var scroll_divs = $("." + div_parent_class_name).children();
    id_offset_map.first = 0;
    scroll_divs.each(function(index) {
        id_offset_map["#" + scroll_divs[index].id] = scroll_divs[index].offsetTop
    });
}

https://jsfiddle.net/561oe7rb/1/

This may not be the most efficient method, but it provides an idea. Apologies for any language errors.

Answer №5

Be amazed by the functionality of this newly crafted page

jQuery(document).on('scroll', function(){
onScroll();

});
jQuery(document).ready(function($) {
div_slider();
showhide();
});

/*reveal or conceal content*/
function showhide(){
$('.toggle-wrapper button').on('click', function(){
$('.wrapper').toggle();
// div_slider();
})
}

/*scroll through page when header elements are clicked*/
function div_slider(){
$('ul li a').on('click', function(e){
e.preventDefault();
$('ul li a').removeClass('active');
$(this).addClass('active');
var attrval = $(this.getAttribute('href'));
$('html,body').stop().animate({
scrollTop: attrval.offset().top
}, 1000)
});
}

/*add active class to header elements as you scroll down the page*/
function onScroll(event){
var scrollPosition = $(document).scrollTop();
$('ul li a').each(function () {
var scroll_link = $(this);
var ref_scroll_Link = $(scroll_link.attr("href"));
if (ref_scroll_Link.position().top <= scrollPosition && ref_scroll_Link.position().top + ref_scroll_Link.height() > scrollPosition) {
$('ul li a').removeClass("active");
scroll_link.addClass("active");
}
else{
scroll_link.removeClass("active");
}
});
}
body {
margin: 0;
}
.toggle-wrapper {
position: fixed;
top: 0;
left: 0;
right: 0;
background-color: #ccd2cc;
text-align: center;
}
.toggle-wrapper button {
background-color: #ED4C67;
color: #ffffff;
padding: 10px 20px;
border: 0;
cursor: pointer;
border-radius: 5px;
}
.toggle-wrapper button:active{
background-color: #B53471;
}
header {
background-color: #6C5CE7;
position: fixed;
top: 36px;
z-index: 99;
left: 0;
right: 0;
}
header ul {
list-style: none;
display: flex;
justify-content: space-between;
align-items: center;
padding: 0;
margin: 0;
}
ul li {
flex: 1 100%;
display: flex;
justify-content: center;
}
.wrapper {
margin-top: 36px;
}
header a {
color: #ffffff;
padding: 15px;
display: block;
text-decoration: navajowhite;
text-transform: uppercase;
width: 100%;
text-align: center;
}
header a.active {
color: #000000;
background-color: #ffffff;
}
section {
height: 100vh;
display: flex;
justify-content: center;
align-items: center;
}
section.section1 {
background-color: #FFEAA7;
}
section.section2{
background-color:#FAB1A0;
}
section.section3{
background-color:#7F8C8D;
}
section.section4{
background-color:#4CD137;
}
section.section5{
background-color:#A3CB38;
}
section.section6{
background-color:#70A1FF;
}
section.section7{
background-color:#079992;
}
<div class="toggle-wrapper">
<button>Toggle</button>
</div>
<div class="wrapper" style="display: none;">
<header>
<ul>
<li><a class="active" href="#one">one</a></li>
<li><a href="#two">two</a></li>
<li><a href="#three">three</a></li>
<li><a href="#four">four</a></li>
<li><a href="#five">five</a></li>
<li><a href="#six">six</a></li>
<li><a href="#seven">seven</a></li>
</ul>
</header>
<section class="section1" id="one">SECTION ONE</section>
<section class="section2" id="two">SECTION TWO</section>
<section class="section3" id="three">SECTION THREE</section>
<section class="section4" id="four">SECTION FOUR</section>
<section class="section5"id="five">SECTION FIVE</section>
<section class="section6" id="six">SECTION SIX</section>
<section class="section7" id="seven">SECTION SEVEN</section>
</div>
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.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

Implementing dynamic classes for each level of ul li using JavaScript

Can anyone help me achieve the goal of assigning different classes to each ul li element in vanilla Javascript? I have attempted a solution using jQuery, but I need it done without using any libraries. Any assistance would be greatly appreciated! con ...

Manage the lineup of tasks in the bull queue by organizing them into groups

I am currently working on a nodejs application that handles queues using the bull library. The application is required to make multiple asynchronous HTTP requests and then process the results of these calls. I'm curious about whether bull would be an ...

Express Form Validation: Ensuring Data Accuracy

I have recently learned that client-side form validations may not be sufficient to prevent malicious actions from users. It is recommended to also validate the form on the server-side. Since I am new to using express, can someone provide guidance on what s ...

Can Vuex mapActions be utilized within a module that is exported?

Is it possible to utilize Vuex mapActions from an external module imported into a component? I am working on standardizing a set of functions in a vue.js web application. My goal is to import these functions into each component and pass necessary values f ...

The code snippet `document.getElementById("<%= errorIcon.ClientID %>");` is returning a null value

I need to set up validation for both the server and client sides on my registration page. I want a JavaScript function to be called when my TextBox control loses focus (onBlur). Code in the aspx page <div id="nameDiv"> <asp:Upd ...

Need help addressing a sliding page issue in my Upwork clone script using JavaScript

For those familiar with Upwork's UI, you may have noticed a small feature I implemented. When a user clicks on a freelance job offer, another page opens from the left side using transform: translate(120%) to transform: translate(0). The issue arises ...

Is it possible to maintain HTML, JS, and CSS files as separate entities when developing Vue.js components, similar to how it is

Is it possible to maintain separate HTML, JS, and CSS files while creating Vue.js components? I recently read the "Why Vue.js doesn't support templateURL" article which discusses this topic. "Proper modularization is a necessity if you want to bu ...

AngularJS and TypeScript encountered an error when trying to create a module because of a service issue

I offer a service: module app { export interface IOtherService { doAnotherThing(): string; } export class OtherService implements IOtherService { doAnotherThing() { return "hello."; }; } angular.mo ...

AJAX/PHP causing delays due to lag problems

I've been trying to implement an asynchronous call in my PHP script, but I keep running into the same issue: "Maximum call stack size exceeded." This is causing severe lag on my site and I suspect there might be a loop somewhere in my code that I just ...

Experiment with the Users.Get function available in vk-io

I am having an issue with a create command: Ban [@durov] and I encountered an error. Here is how I attempted to solve the problem: let uid = `${message.$match[1]}` let rrr = uid.includes('@') if(rrr == true){ let realid = uid.replace(/[@]/g, &ap ...

Display the final row by hovering over the line

<table> <thead> <tr> <th>First</th> <th>Second</th> <th></th> </tr> </thead> <tbody> <tr> <td>Data1</td> <td>Dat ...

Tips on how to change the color scheme of a webpage

I am currently working with basic HTML and CSS, but I am facing an issue where my background color is only filling a third of the page instead of the entire page. Despite attempting to use the html and body classes for the background color, it did not prod ...

No results found for the xpath within the <p> tag

I'm currently using selenium.webdriver chrome to scrape data from my website, and I need to extract the location details of visitors. Although I have successfully identified the <p> tag that contains 'location', it is returning None. ...

Why am I encountering the "500 (Internal Server Error) when utilizing Wordpress with Ajax and trying to make a POST request to http://54.xx.xx.xx/wp-admin/admin-ajax.php?

Today marks my first attempt at utilizing ajax on WP. As I dive into creating a simple contact form, an error keeps cropping up whenever I hit submit: Displayed in the console: POST http://54.xxx.xx.xx/wp-admin/admin-ajax.php 500 (Internal Server Error) ...

Step-by-step guide on creating a login functionality in Node using the Mean.io stack

I'm currently working on a web app using the MEAN.io stack. I have completed the frontend part with HTML, CSS, and AngularJS along with some logic. Now, I am looking to implement server-side login functionality, but I'm unsure where to begin sinc ...

AngularJs Datepicker malfunctioning after Data-dismiss operation

When using jquery datepicker in a AngularJs modal, it is important to initialize it correctly. Here is an example: <div class="col-md-2 rowdatepicker"> <label> RECORDING DATE </label> <input type="text" class="abs- ...

User authentication using .pre save process

I have an API that accepts users posted as JSON data. I want to validate specific fields only if they exist within the JSON object. For example, a user object could contain: { "email" : "<a href="/cdn-cgi/l/email-protection" class="__cf_email__" dat ...

Retrieve information using AJAX via POST method

I find myself in a bit of a pickle at the moment. I've been researching for hours, and I still can't seem to figure out this seemingly basic issue. It would be greatly appreciated if someone could offer me some quick advice. So here's my dil ...

Could it be feasible to manage several ongoing asynchronous requests simultaneously?

Visualize a grid in which the user completes cell A1 and presses Enter to move to A2. As this happens, a request is sent to the backend to search a database and retrieve results for populating the remaining cells in row A. Meanwhile, I want the user to con ...

Discover how to initiate an ajax request from a tailored module when the page is loaded in ActiveCollab

When trying to initiate an AJAX call on the project brief page by adding a JavaScript file, I encountered some issues. My goal is to display additional information along with the existing project brief. I included a JavaScript file in a custom module and f ...