我试图用进度条显示用户在页面 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%
。我不明白为什么我在这里错了!
所以,我的问题是为什么我们需要从 windowHeight
减少 html.clientHeight
?
谢谢。
此处演示:
// --------------------------------------------
// 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>
最佳答案
举个例子,假设您的客户端高度为 100px
,整个页面的高度为 500px
。
当滚动位置为 0px
时,您可以看到网站的前 100px
,因此从 0px
到 >100px
。
在滚动位置 100px
处,您可以看到范围 100px
到 200px
,因为您已经移动了页面,因此可见范围,以 100px
为单位。
在滚动位置 400px
处,您可以看到 400px
到 500px
的范围 - 换句话说,您已滚动到底部.
这表明页面的可滚动高度 (400px
) 小于页面的实际高度 (500px
),即客户端的高度。
要获得滚动的百分比,需要使用可滚动的高度,因此需要用页面的高度减去客户端的高度才能得到正确的值,否则永远无法滚动到底端。在只有 500px
长的网站上不可能滚动 500px
!
关于javascript - 为什么在计算scrollPercent时需要从windowHeight减少clientHeight?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61478766/