Tips for stopping the hidden div from automatically scrolling

To optimize performance, I have decided not to create many .HTML files. Instead, I am putting the page content into a div so that it will display as follows:

<div id="page1"> first page content</div>
<div id="page2"> first page content</div>
<div id="page3"> first page content</div>
<div id="page4"> first page content</div>

However, I encountered an issue where the second page automatically scrolls when I scroll on the first page, even if the second page is hidden.

PAGE 1 - 1
PAGE 1 - 2
PAGE 1 - 3
PAGE 1 - 4
PAGE 1 - 5
PAGE 1 - 6
PAGE 1 - 7
PAGE 1 - 8
PAGE 1 - 9
PAGE 1 - 10
PAGE 1 - 11
PAGE 1 - 12
PAGE 1 - 13
PAGE 1 - 14
PAGE 1 - 15
PAGE 1 - 16
PAGE 1 - 17
PAGE 1 - 18
PAGE 1 - 19
PAGE 1 - 20
PAGE 1 - 21
PAGE 1 - 22
PAGE 1 - 23
PAGE 1 - 24
PAGE 1 - 25
PAGE 1 - 26
PAGE 1 - 27
PAGE 1 - 28
PAGE 1 - 29
PAGE 1 - 30
PAGE 1 - 31
PAGE 1 - 32
PAGE 1 - 33
PAGE 1 - 34
PAGE 1 - 35
PAGE 1 - 36
PAGE 1 - 37
PAGE 1 - 38
PAGE 1 - 39
PAGE 1 - 40
PAGE 1 - 41
PAGE 1 - 42
PAGE 1 - 43
PAGE 1 - 44
PAGE 1 - 45
PAGE 1 - 46
PAGE 1 - 47
PAGE 1 - 48
PAGE 1 - 49
PAGE 1 - 50
PAGE 1 - 51

I understand the solution requires saving the final scrolling point and implementing scroll functions, but with over 30 pages, managing this manually becomes very cumbersome.

Answer №1

In your provided HTML sample, an alternative method is to deal with your comment within the original post:

It may seem complex to save and scroll to the final position when returning to the first page, especially with over 30 pages.

A simpler solution involves: adding a page number attribute to each page element (representing your generated HTML content); creating a key/value object entry; associating the page number as the key and storing the scrollTop value before displaying another page element as the value.

const pageContainerEl = document.documentElement;

const savedScrollTops = {};

document.querySelectorAll("button[data-page-num]")
  .forEach(btn => btn.addEventListener("click", clickHandler));

setActivePage("1");

function clickHandler() {

   const pageNum = this.getAttribute("data-page-num");

  setActivePage(pageNum);
}

function setActivePage(pageNum) {

  pageNum = parseInt(pageNum, 10);

  if (!Number.isInteger(pageNum)) {
    return;
  }

  const activePageEl = document.querySelector(".page.active");

  if (activePageEl) {

    const activePageNum =
      parseInt(activePageEl.getAttribute("data-page-num"), 10);

    if (activePageNum === pageNum) {
      return;
    }

    if (Number.isInteger(activePageNum)) {
      savedScrollTops[`pageNum${activePageNum}`] =
        pageContainerEl.scrollTop;
    }

    activePageEl.classList.remove("active");
  }

  const pageEl = document.querySelector(`.page[data-page-num='${pageNum}']`);
  if (!pageEl) {
    return;
  }

  pageEl.classList.add("active");

  pageContainerEl.scrollTop =
    savedScrollTops[`pageNum${pageNum}`] || 0;
}
html {
  /* https://developer.mozilla.org/en-US/docs/Web/CSS/scroll-behavior */
  scroll-behavior: unset !important;
}

#button-controls {
  position: fixed;
  display: grid;
  grid-auto-flow: column;
  grid-gap: 1rem;
  width: fit-content;
}

.page {
  display: none;
}

.page.active {
  display: block;
}
<span id="button-controls">
    <button data-page-num="1">Show page 1</button>
    <button data-page-num="2">Show page 2</button>
</span>

<div id="page1" class="page" data-page-num="1">
...Content for Page 1...
</div>

<div id="page2" class="page" data-page-num="2">
...Content for Page 2...
</div>

Answer №2

Here is a potential solution:

  • Create a container for the main pages that expands to occupy all available space
  • Arrange the pages to overlap each other using absolute positioning and enable scrolling with overflow: auto
  • Whenever a page gets the class "is-active", set its scroll position to the top (scrollTop = 0)
    // Helper functions:
    
    const findElement = (selector, parent) => (parent || document).querySelector(selector);
    const findAllElements = (selector, parent) => [...(parent || document).querySelectorAll(selector)];
    const createNewElement = (tag, props) => Object.assign(document.createElement(tag), props);
    
    // Task: Pages 
    
    const pageSelector = findElement("#toPage");
    const pagesContainer = findElement("#pages");
    
    const createSinglePage = (pageData, index) => {
      const newPage = createNewElement("article", {
        className: "page",
        innerHTML: `<p><i>Page Number: ${index+1}</i></p>
                    <h2>${pageData.title}</h2>
                    <div>${pageData.body}</div>`
      });
      
      const optionForPage = createNewElement("option", {
        textContent: index+1,
        value: index,
      });
      
      pageSelector.append(optionForPage);
      pagesContainer.append(newPage);
    };
    
    const displayPage = (pageIndex) => {
      pagesContainer.querySelector(".page.is-active")?.classList.remove("is-active"); 
      pagesContainer.children[pageIndex].scrollTop = 0;
      pagesContainer.children[pageIndex].classList.add("is-active");
    };
    
    pageSelector.addEventListener("input", (event) => {
      displayPage(+pageSelector.value);
    });
      
    // Fetch content and show first page
    fetch("https://jsonplaceholder.typicode.com/posts")
      .then(response => response.json())
      .then(dataReceived => {
        dataReceived.forEach(createSinglePage);
        displayPage(0);
    });
    * { box-sizing: border-box; }
    
    body {
      margin: 0; 
      min-height: 100vh;
      display: flex;
      flex-direction: column;
    }
    
    #nav {
      background: gold;
      padding: 1rem;
    }
    
    #pages {
      position: relative;
      background: #ddd;
      flex: 1;
    }
    
    .page {
      position: absolute;
      top:0;
      left: 0;
      right: 0;
      bottom: 0;
      overflow: auto;
      padding: 1rem;
      margin: auto;
      opacity: 0;
      transition: opacity 0.3s, scale 0.3s;
      scale: 0.7;
      pointer-events: none;
      font-size: 12vmin;
    }
    
    .page.is-active {
      opacity: 1;
      pointer-events: auto;
      scale: 1;
    }
    <nav id="nav">Page:
      <select id="toPage"></select>
    </nav>
    <main id="pages"></main>

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

Tips for importing extensions with Rselenium

I could use some assistance in understanding how to activate a chrome extension using RSelenium. The extensions are visible in the browser tabs but are not automatically loaded when working with RSelenium. https://i.sstatic.net/QKqVg.png ...

An error occurs with Three JS when trying to access a S3 Bucket used as a CDN due to Cross Origin

function displayItem() { startScene(); THREE.ImageUtils.crossOrigin = "anonymous"; var mtlLoader = new THREE.MTLLoader(); mtlLoader.setTexturePath('https://cdn.rubyrealms.com/textures/'); mtlLoader.setPath('https://cdn.ru ...

Play a diverse selection of audio variables at random

As I prepare to transition into the view, I would like the controller to select a random audio file and play it. I'm feeling a bit lost on where to even begin with this task. Controller: var audioOne = new Audio("img/1.mp3"); var audioTwo = new Audi ...

Invoking PHP code from within Javascript will output the function as a direct string

I seem to be going in circles and missing something silly... My setup involves using CodeIgniter on the server-side and Bootstrap on the client, but that's not really the issue here... I am attempting to access a PHP value within a JavaScript functi ...

Error encountered while trying to embed SVG file

My method involves utilizing an ajax call to fetch an htm file that constructs an SVG. Although the call retrieves the file successfully, the designated area where it should display only shows: https://i.sstatic.net/8G9IU.jpg Could this issue be related ...

Is it possible to apply a tailwind class that fades or transitions into something else after a specific duration?

How can I achieve a transition effect from the bg-red-300 class to bg-transparent, or a different background class, over a 2-second duration? Do I need to use javascript for this effect? I would like an element to be highlighted and then return to its no ...

Encountered an error with @angular-cli/ast-tools during the installation of angular-cli on a Mac running OS X (El Capitan

While attempting to install the latest version of @angular-cli on my Mac OS X (El Capitan) using the command sudo npm install -g @angular-cli@latest, I encountered the following error: Darwin 15.4.0 npm ERR! argv "/usr/local/bin/node" "/usr/local/bin/npm" ...

Modify the color of the text input border upon interaction using CSS

Changing text input border color using CSS upon clicking Hey there! I have a text field in my HTML: <input type="text" value="test" id="ff"> Currently, I am using the following CSS to define its border: #ff { border: 1px solid #000; } I would ...

Consistently maintaining a uniform distance between icons and the border box is essential

I am working on a team overview for a company where data such as name, job title, and information are fetched from the database. Due to varying lengths of information, the icons are not aligning properly in one line. https://i.sstatic.net/cEmKj.png Does ...

How to dynamically change the title of a group box in Angular 8 using TypeScript

I am working with a component that includes a groupbox: <fieldset> <legend>Title</legend> </fieldset> Could I change the title of the groupbox using TypeScript code? ...

What is the best way to align the 5th and 6th list items to the left using CSS?

I am experimenting with Bootstrap to create a customized navbar. I am encountering difficulties in aligning the login and logout buttons to the right. Is there a way to achieve this? I have included my HTML and CSS code below: HTML code: <body> &l ...

How does webpack identify the index.html file as the entry point for loading the bundle.js file?

I've noticed that without specifying a command to load index.html, webpack is automatically loading the page whenever I make changes in a file. Below are the attached files: webpack.config.js and package.json webpack.config.js var config = { entry: ...

Using a Default Value in a Destructured Function Parameter Results in a ReferenceError

When working on setting a default value for the db in my CRUD functions for testing purposes, I encountered a peculiar issue that has left me puzzled. Here's the snippet of code that caused the trouble: import { db } from './firebase' func ...

React error message: "Cannot update state on a component that is not mounted" unless using the useEffect hook

(I am a beginner using Next.js + Styled Components and need help :)) I'm currently working on creating a "Netflix" style page, with unique catalog components. Each content item in the grid is a complex component named ContentItem.js that is repeated ...

Navigating to a precise element within a page in Angular with flawless redirection

I recently encountered an issue where I had to add a span element with a specific ID in my HTML code to ensure that clicking on the Reply button would navigate to it. However, this modification was only necessary for the last element on the page. While the ...

Using jQuery, you can retrieve data from a specific sheet in Google Sheets API by executing a

Is there a way to access cells from different sheets within a Google spreadsheet? Currently, I am able to access a range of cells from the default first sheet using the following code: var url = 'https://docs.google.com/spreadsheets/d/' + spread ...

function call should encompass the input content

I am currently trying to incorporate the content of a text box into a function call. Here is what I have so far: <form name="blah"> <input type="text" name="compdate" id="compdate" readonly onClick="GetDate(this);" /> <input type="button" o ...

Error: "Illuminate\Database\QueryException" - Unable to locate column with ID 1054 in Laravel 8

To edit data, it needs to be displayed in a form. The primary key in my database table is called id_casting. Below is the code snippet: Script : $(document).on('click', '.edit', function(){ var id = $(this).attr('id&a ...

Ensure accuracy when converting to a float data type

My dilemma involves sending numerical values to a server using an AJAX call. For instance, numbers like 0.77, 100, and similar variations are being transmitted. However, upon reaching the server, the data is being interpreted differently - 0.77 as a double ...