Зачем нужно уменьшать clientHeight из windowHeight при расчете scrollPercent? - PullRequest
1 голос
/ 28 апреля 2020

Я пытаюсь показать, сколько пользователь прокрутил страницу a с индикатором выполнения, и я сделал это. Но здесь у меня небольшая путаница.

Вот код, который я нашел для вычисления scrollPercent, который хорошо работает


windowHeight = Math.max(
html.clientHeight,
html.scrollHeight,
html.offsetHeight,
body.scrollHeight,
body.offsetHeight
);

const  scrolledPercent =
((html.scrollTop || body.scrollTop) / (windowHeight - html.clientHeight)) *
100;

Изначально, я думал, чтобы получить scrollPercent, Мне нужно получить текущее значение scrollPosition, разделить это число на общую высоту страницы и умножить на 100%. это как обычно то, как мы получаем % чего-то.

const  scrolledPercent = 
((html.scrollTop || body.scrollTop) / windowHeight) * 100;

, но эта строка работает не так, как я ожидал. Если я сделаю это, индикатор выполнения не достигнет 100%, даже если прокрутить до конца страницы. Я не понимаю, почему я здесь не так!

Итак, мой вопрос: почему мы должны уменьшить html.clientHeight с windowHeight?

Спасибо.

Демо здесь:

// --------------------------------------------
// variables
// --------------------------------------------

const html = document.documentElement,
  body = document.body,
  countryList = document.querySelector(".country__list");
scrollNavigated = document.querySelector(".scroll__navigated");
let windowHeight;

// --------------------------------------------
// function
// --------------------------------------------

async function prepareListOfCountries() {
  let list = await fetch("https://restcountries.eu/rest/v2/all");
  list = Array.from(await list.json());
  let markup = list
    .map((country, index) => {
      return `<li class="country__item card">
              <span class="country__name">${country.name}</span
              ><span class="country__capital">${country.capital}</span>
              <a href="javascript:;" class="country__flag">
               <img src= '${country.flag}'> </a>
             
        </li>`;
    })
    .slice(0, 30)
    .join(" ");
  countryList.innerHTML = markup;
}

function updateScrolledStatus(e) {
  windowHeight = Math.max(
    html.clientHeight,
    html.scrollHeight,
    html.offsetHeight,
    body.scrollHeight,
    body.offsetHeight
  );

  const scrolledPercent =
    ((html.scrollTop || body.scrollTop) / (windowHeight - html.clientHeight)) *
    100;
  // const scrolledPercent =
  //   ((html.scrollTop || body.scrollTop) / windowHeight) * 100; // this line doesnot work
  scrollNavigated.style.width = scrolledPercent + "%";
}

prepareListOfCountries();

// --------------------------------------------
// event-handler
// --------------------------------------------

window.addEventListener("scroll", updateScrolledStatus);
*::after,
*::before,
* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

body {
  background: #fff;
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen,
 Ubuntu, Cantarell, "Open Sans", "Helvetica Neue", sans-serif;
}

.container {
  max-width: 980px;
  margin: 0 auto;
}

.justify-between {
  display: flex;
  align-items: center;
  justify-content: space-between;
}

.items-center {
  display: flex;
  align-items: center;
}

.card {
  background-color: #fff;
  box-shadow: 0 0 12px 12px rgba(0, 0, 0, 0.054);
  border-radius: 4px;
  padding: 16px;
}

.country__flag img {
  height: 100%;
  width: 100%;
}

.header {
  padding: 24px 0;
  background-color: #333;
  color: #f1f1f1;
  position: -webkit-sticky;
  position: sticky;
}

.content {
  padding: 50px 0;
}

.content__form {
  margin: 0 auto;
  margin-bottom: 32px;
}

.content__search {
  width: 50%;
  padding: 12px 16px;
  border-radius: 20px;
  border: 1px solid #ddd;
  transition: 0.2s;
}

.content__search:hover {
  box-shadow: 0 1px 6px 0 rgba(32, 33, 36, 0.28);
}

.content__search:focus {
  outline: none;
}

.country__list {
  margin-top: 50px;
  margin: 10px auto;
}

.country__item {
  display: flex;
  justify-content: space-between;
  margin-bottom: 16px;
}

.country__name, .country__capital, .country__flag {
  width: 33.33%;
}

.country__flag {
  width: 32px;
  height: 24px;
}

.scroll__navigator {
  height: 2px;
  margin: 0 auto 32px;
  background-color: #333;
  position: -webkit-sticky;
  position: sticky;
  top: 0;
}

.scroll__navigated {
  display: block;
  height: 100%;
  width: 0;
  background: orangered;
  transition: 0.3s linear;
}
<body>
    <header class="header">
      <div class="container">
        All countries list
      </div>
    </header>
    <main class="content">
      <div class="container">
        <form class="content__form">
          <input class="content__search" />
        </form>
        <div class="scroll__navigator">
          <span class="scroll__navigated"></span>
        </div>
        <section class="country">
          <ul class="country__list">
            <li class="country__item card">
              <span class="country__name">Nepal</span
              ><span class="country__capital">Kathmandu</span>
              <a href="javascript:;" class="country__flag"></a>
            </li>
          </ul>
        </section>
      </div>
    </main>
     
  </body>
 

1 Ответ

1 голос
/ 28 апреля 2020

В качестве примера, скажем, что высота вашего клиента равна 100px, а высота всей вашей страницы равна 500px.

Когда позиция прокрутки равна 0px, вы можете см. первый 100px вашего сайта, поэтому от 0px до 100px.

В позиции прокрутки 100px вы можете видеть диапазон от 100px до 200px, потому что вы переместил страницу и, следовательно, видимый диапазон, на 100px.

В позиции прокрутки 400px вы можете увидеть диапазон от 400px до 500px - другими словами, вы прокручивается к низу.

Это показывает, что высота прокручиваемой страницы (400px) меньше, чем фактическая высота страницы (500px), а именно высота клиента.

Чтобы получить прокручиваемый процент, вам нужно использовать высоту прокрутки, поэтому необходимо вычесть высоту клиента из высоты страницы, чтобы получить правильное значение, иначе прокрутка вам не удастся ко дну. Невозможно прокрутить на 500px на сайте длиной всего 500px!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...