Как предотвратить автоматическую прокрутку скрытого div

Для производительности я не создаю много файлов .HTML. Вместо этого я создаю содержимое страницы в div, поэтому оно будет отображаться, как показано ниже.

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

Но проблема в том, что вторая страница автоматически прокручивается, когда я прокручиваю первую страницу, даже вторая страница скрыта.

<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

Я знаю решение, мы можем сохранить конечную точку прокрутки, и мы можем прокручивать, когда дойдем до первой страницы, и мы можем использовать scrolltotop, но это очень сложно, потому что у меня более 30 страниц.

Подождите... у вас есть более 30 кнопок с надписью "Показать страницу N"? Кроме того, что мешает вам использовать .scrollTop = 0; на прокручиваемом элементе?

Roko C. Buljan 17.02.2023 11:29

Ошибка, которую вы здесь делаете, заключается в том, что вы на самом деле прокручиваете не DIV, а весь документ. Так что ваше предположение ошибочно. Вместо этого используйте .page для всех своих страниц, стилизуйте их в CSS, чтобы иметь overflow: auto; Теперь все ваши страницы можно прокручивать независимо. Что вы, возможно, захотите сделать в конечном итоге, так это scrollTop = 0; активная страница - при необходимости.

Roko C. Buljan 17.02.2023 11:30

@RokoC.Buljan, спасибо за ваш комментарий, на самом деле я использую это для своего приложения Cordova. Нет 30 кнопок для отображения каждой страницы, кнопки каждой страницы связаны между собой. Я пытался написать «переполнение: авто», но это не работает, не могли бы вы внести изменения в ссылку codepen и дать?

Merbin Joe 17.02.2023 11:40

Попробуйте установить style = "position:absolute; left:0; top:0; width:100vw; height:100vh; overflow:auto;".

Michael G 17.02.2023 11:59
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
1
4
57
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Один из возможных подходов:

  • Создайте оболочку главной страницы, которая изгибается 1 (занимает доступное место)
  • Сделайте так, чтобы ваши страницы перекрывали друг друга, используя абсолютную позицию и установите overflow: auto
  • Когда страница становится классом "is-active", установите ее scrollTop на 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>

Не могли бы вы внести изменения в следующий код? Вышеприведенное очень сложно и не решает мою проблему, потому что, если я прокручиваю страницу 1 и перехожу на страницу 2, эта страница 2 должна отображаться с первой строки, а затем, если я нажимаю кнопку «Назад», страница 1 должна отображаться откуда мы ушли.

Merbin Joe 17.02.2023 13:11

@MerbinJoe, если это так, удалите строку elPages.children[index].scrollTop = 0;

Roko C. Buljan 17.02.2023 13:23

Извините, я не могу понять код.

Merbin Joe 17.02.2023 13:30
Ответ принят как подходящий

Другой подход, использующий ваш образец HTML, состоит в том, чтобы обратиться к вашему комментарию в исходном сообщении:

Я знаю решение, мы можем сохранить конечную точку прокрутки, и мы можем прокручивать, когда дойдем до первой страницы, и мы можем использовать scrolltotop, но это очень сложно, потому что у меня более 30 страниц.

Простое решение состоит в том, чтобы: присвоить атрибут номера страницы каждому элементу страницы (т. е. сгенерированной странице HTML-контента); добавить запись в объект key/value; присвоить key значению атрибута номера страницы; назначьте value позиции scrollTop, полученной непосредственно перед отображением другого элемента страницы.

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>

Другие вопросы по теме