skip to Main Content

For performance, I am not creating many .HTML files. Instead of it I am creating the page content into a div so it will be show like below

<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>

But the problem is, the second page automatically scroll, when I scroll the first page even the second page is hidden.

<button style="position:fixed" onclick="page1.style.display='none';page2.style.display='';">Show page 2</button>
<button style="position:fixed;margin-left:100px" onclick="page1.style.display='';page2.style.display='none';">Show page 1</button>

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

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

The sample in codepen
https://codepen.io/merbin2012/pen/qBMdVKZ?editors=1000

I know the solution, we can save the final scrolling point and we can scroll when come to the first page and we can use scrolltotop, but it is very difficult to manage, because I have more than 30pages.

2

Answers


  1. One possible approach:

    • Create a main pages wrapper that flexes 1 (occupy available space)
    • Make your pages overlap each-other using position absolute and set overflow: auto
    • When a page becomes class "is-active" set its scrollTop to 0
      // DOM utility functions:
      
      const el = (sel, par) => (par || document).querySelector(sel);
      const els = (sel, par) => (par || document).querySelectorAll(sel);
      const elNew = (tag, prop) => Object.assign(document.createElement(tag), prop);
      
      
      // Task: Pages 
      
      const elToPage = el("#toPage");
      const elPages = el("#pages");
      
      const createPage = (page, i) => {
        const elPage = elNew("article", {
          className: "page",
          innerHTML: `<p><i>Page: ${i+1}</i></p>
                      <h2>${page.title}</h2>
                      <div>${page.body}</div>`
        });
        const elOption = elNew("option", {
          textContent: i+1,
          value: i,
        });
        
        elToPage.append(elOption);
        elPages.append(elPage);
      };
      
      const showPage = (index) => {
        elPages.querySelector(".page.is-active")?.classList.remove("is-active"); 
        elPages.children[index].scrollTop = 0;
        elPages.children[index].classList.add("is-active");
      };
      
      elToPage.addEventListener("input", (evt) => {
        showPage(+elToPage.value);
      });
        
      // Grab content and show first page
      fetch("https://jsonplaceholder.typicode.com/posts")
        .then(res => res.json())
        .then(data => {
          data.forEach(createPage);
          showPage(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>
    Login or Signup to reply.
  2. Another approach using your HTML sample is to address your comment in your original post:

    I know the solution, we can save the final scrolling point and we can scroll when come to the first page and we can use scrolltotop, but it is very difficult to manage, because I have more than 30pages.

    A straightforward solution is to: assign a page number attribute to each page element (i.e. your generated HTML content page); add an entry to a key/value object; assign the key to the page number attribute value; assign value to the scrollTop position retrieved just before another page element is displayed.

    const pageContainerEl = document.documentElement;
    
    const savedScrollTops = {};
    
    document.querySelectorAll("button[data-page-num]")
      .forEach(btn => btn.addEventListener("click", clickHandler));
    
    setActivePage("1");
    
    function clickHandler() {
      // 'this' represents the 'button' element that was clicked.
      // Get the page number in the 'data-page-num' attribute
      // of the clicked button.
      const pageNum = this.getAttribute("data-page-num");
    
      setActivePage(pageNum);
    }
    
    // 'pageNum' parameter can be a integer (e.g. 4) 
    // or a string representing an integer value (e.g. "5");
    function setActivePage(pageNum) {
      // If the 'pageNum' parameter is set to a string
      // then convert the string to an integer using the
      // built-in 'parseInt()' function.
      pageNum = parseInt(pageNum, 10);
    
      // If the value assigned to the 'pageNum' parameter is
      // not an integer then exit this function.
      if (!Number.isInteger(pageNum)) {
        return;
      }
    
      // Get the active page element
      const activePageEl = document.querySelector(".page.active");
    
      if (activePageEl) {
        // If an active page element exists, get it's
        // 'data-page-num' attribute value and assign it to
        // the variable 'activePageNum'.
        const activePageNum =
          parseInt(activePageEl.getAttribute("data-page-num"), 10);
    
        // If the requested page number set in the parameter
        // 'pageNum' is the same as the active page number
        // then exit this function as no more code needs to
        // be executed.
        if (activePageNum === pageNum) {
          return;
        }
    
        if (Number.isInteger(activePageNum)) {
          savedScrollTops[`pageNum${activePageNum}`] =
            pageContainerEl.scrollTop;
        }
    
        // Hide the active page element by removing the
        // 'active' class name.
        activePageEl.classList.remove("active");
      }
    
      // Find the page element that has a 'data-page-num'
      // attribute value equal to the value assigned to the
      // 'pageNum' parameter.
      const pageEl = document.querySelector(`.page[data-page-num='${pageNum}']`);
      if (!pageEl) {
        return;
      }
    
      // Display the page element
      pageEl.classList.add("active");
    
      // Change the vertical scroll position of the page
      // element to the stored scroll top value in the
      // 'savedScrollTops' object.
      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">
      <div>PAGE 1 - 1</div>
      <div>PAGE 1 - 2</div>
      <div>PAGE 1 - 3</div>
      <div>PAGE 1 - 4</div>
      <div>PAGE 1 - 5</div>
      <div>PAGE 1 - 6</div>
      <div>PAGE 1 - 7</div>
      <div>PAGE 1 - 8</div>
      <div>PAGE 1 - 9</div>
      <div>PAGE 1 - 10</div>
      <div>PAGE 1 - 11</div>
      <div>PAGE 1 - 12</div>
      <div>PAGE 1 - 13</div>
      <div>PAGE 1 - 14</div>
      <div>PAGE 1 - 15</div>
      <div>PAGE 1 - 16</div>
      <div>PAGE 1 - 17</div>
      <div>PAGE 1 - 18</div>
      <div>PAGE 1 - 19</div>
      <div>PAGE 1 - 20</div>
      <div>PAGE 1 - 21</div>
      <div>PAGE 1 - 22</div>
      <div>PAGE 1 - 23</div>
      <div>PAGE 1 - 24</div>
      <div>PAGE 1 - 25</div>
      <div>PAGE 1 - 26</div>
      <div>PAGE 1 - 27</div>
      <div>PAGE 1 - 28</div>
      <div>PAGE 1 - 29</div>
      <div>PAGE 1 - 30</div>
      <div>PAGE 1 - 31</div>
      <div>PAGE 1 - 32</div>
      <div>PAGE 1 - 33</div>
      <div>PAGE 1 - 34</div>
      <div>PAGE 1 - 35</div>
      <div>PAGE 1 - 36</div>
      <div>PAGE 1 - 37</div>
      <div>PAGE 1 - 38</div>
      <div>PAGE 1 - 39</div>
      <div>PAGE 1 - 40</div>
      <div>PAGE 1 - 41</div>
      <div>PAGE 1 - 42</div>
      <div>PAGE 1 - 43</div>
      <div>PAGE 1 - 44</div>
      <div>PAGE 1 - Slighly shorter content than page 2</div>
    </div>
    
    <div id="page2" class="page" data-page-num="2">
      <div>PAGE 2 - 1</div>
      <div>PAGE 2 - 2</div>
      <div>PAGE 2 - 3</div>
      <div>PAGE 2 - 4</div>
      <div>PAGE 2 - 5</div>
      <div>PAGE 2 - 6</div>
      <div>PAGE 2 - 7</div>
      <div>PAGE 2 - 8</div>
      <div>PAGE 2 - 9</div>
      <div>PAGE 2 - 10</div>
      <div>PAGE 2 - 11</div>
      <div>PAGE 2 - 12</div>
      <div>PAGE 2 - 13</div>
      <div>PAGE 2 - 14</div>
      <div>PAGE 2 - 15</div>
      <div>PAGE 2 - 16</div>
      <div>PAGE 2 - 17</div>
      <div>PAGE 2 - 18</div>
      <div>PAGE 2 - 19</div>
      <div>PAGE 2 - 20</div>
      <div>PAGE 2 - 21</div>
      <div>PAGE 2 - 22</div>
      <div>PAGE 2 - 23</div>
      <div>PAGE 2 - 24</div>
      <div>PAGE 2 - 25</div>
      <div>PAGE 2 - 26</div>
      <div>PAGE 2 - 27</div>
      <div>PAGE 2 - 28</div>
      <div>PAGE 2 - 29</div>
      <div>PAGE 2 - 30</div>
      <div>PAGE 2 - 31</div>
      <div>PAGE 2 - 32</div>
      <div>PAGE 2 - 33</div>
      <div>PAGE 2 - 34</div>
      <div>PAGE 2 - 35</div>
      <div>PAGE 2 - 36</div>
      <div>PAGE 2 - 37</div>
      <div>PAGE 2 - 38</div>
      <div>PAGE 2 - 39</div>
      <div>PAGE 2 - 40</div>
      <div>PAGE 2 - 41</div>
      <div>PAGE 2 - 42</div>
      <div>PAGE 2 - 43</div>
      <div>PAGE 2 - 44</div>
      <div>PAGE 2 - 45</div>
      <div>PAGE 2 - 46</div>
      <div>PAGE 2 - 47</div>
      <div>PAGE 2 - 48</div>
      <div>PAGE 2 - 49</div>
      <div>PAGE 2 - 50</div>
      <div>PAGE 2 - 51</div>
    </div>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search