你可以如何计算元素的滚动位置作为百分比?

huangapple go评论105阅读模式
英文:

How can I calculate an elements scroll position as a percentage?

问题

我想计算窗口内元素的滚动位置,以百分比表示。

  • 0%表示元素顶部位于窗口底部(尚未显示)
  • 100%表示元素底部位于窗口顶部(整个元素已显示)

我离成功不远,但我知道我的数学思维有问题。我制作了一个小演示来显示多个元素的滚动百分比,但百分比都不正确。

function getElemScrollPercent(selector){
  const scale = 0.1;
  const el = document.querySelector(selector);
  const out = el.querySelector('.out');
  
  function calc(){
    const rect = el.getBoundingClientRect();

    // 如果不在屏幕上,则不必计算
    if (rect.top < window.innerHeight && rect.bottom > 0) {
      const total = (window.scrollY) / (rect.bottom + rect.height);
      const pct = total * 100;

      out.innerHTML = `${Math.round(pct)}%`;
    }
  }
  
  window.addEventListener('scroll', calc);
  calc();
}

getElemScrollPercent('#one');
getElemScrollPercent('#two');
getElemScrollPercent('#three');
* { box-sizing: border-box; }
body { display: flex; flex-direction: column; min-height: 400vh }
section {
  height: 100vh;
  position: relative;
  border: 1px solid black;
}
#one   { background:#d1b4b4; }
#two   { background:#b4d1bc; }
#three { background:#b4b5d1; }
.out {
  position: sticky;
  top: 0;
  display: inline-block;
  padding: .5rem;
  background: #CCC;
}
<section id="one">   <span class='out'>%</span> </section>
<section id="two">   <span class='out'>%</span> </section>
<section id="three"> <span class='out'>%</span> </section>
英文:

I would like to calculate the scroll position of an element within the window as a percentage.

  • 0% is where the top of the element is at the bottom of the window (it has not been shown yet)
  • 100% is where the bottom of the element is at the top of the window (all of the element has been shown)

I am close, but I know I'm thinking about something in my math wrong. I've put together a little demo to show the scroll percentage for multiple elements, but the percents are all wrong.

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-js -->

function getElemScrollPercent(selector){
  const scale = 0.1;
  const el = document.querySelector(selector);
  const out = el.querySelector(&#39;.out&#39;);
  
  function calc(){
    const rect = el.getBoundingClientRect();

    //don&#39;t bother calculating if it&#39;s off screen
    if (rect.top &lt; window.innerHeight &amp;&amp; rect.bottom &gt; 0) {
      const total = (window.scrollY) / (rect.bottom + rect.height);
      const pct = total * 100;

      out.innerHTML = `${Math.round(pct)}%`;
    }
  }
  
  window.addEventListener(&#39;scroll&#39;, calc);
  calc();
}

getElemScrollPercent(&#39;#one&#39;);
getElemScrollPercent(&#39;#two&#39;);
getElemScrollPercent(&#39;#three&#39;);

<!-- language: lang-css -->

* { box-sizing: border-box; }
body { display: flex; flex-direction: column; min-height: 400vh }
section {
  height: 100vh;
  position: relative;
  border: 1px solid black;
}
#one   { background:#d1b4b4; }
#two   { background:#b4d1bc; }
#three { background:#b4b5d1; }
.out {
  position: sticky;
  top: 0;
  display: inline-block;
  padding: .5rem;
  background: #CCC;
}

<!-- language: lang-html -->

&lt;section id=&quot;one&quot;&gt;   &lt;span class=&#39;out&#39;&gt;%&lt;/span&gt; &lt;/section&gt;
&lt;section id=&quot;two&quot;&gt;   &lt;span class=&#39;out&#39;&gt;%&lt;/span&gt; &lt;/section&gt;
&lt;section id=&quot;three&quot;&gt; &lt;span class=&#39;out&#39;&gt;%&lt;/span&gt; &lt;/section&gt;

<!-- end snippet -->

答案1

得分: 0

我认为你在这些行的数学计算上有一些问题,就像你所指出的一样:

const total = (window.scrollY) / (rect.bottom + rect.height);
const pct = total * 100;

尝试使用以下代码替换这些行:

const scrollableDistance = window.innerHeight + rect.height;
const scrolled = window.innerHeight - rect.top;

const pct = (scrolled / scrollableDistance) * 100;

请告诉我这是否解决了你的问题,这样我就可以建议其他解决方法。

英文:

Just like you've pointed out, I think you have something wrong with the math at these lines:

  const total = (window.scrollY) / (rect.bottom + rect.height);
  const pct = total * 100;

Try changing those lines with this:

const scrollableDistance = window.innerHeight + rect.height;
const scrolled = window.innerHeight - rect.top;

const pct = (scrolled / scrollableDistance) * 100;

Let me know if this solves your problem so I can suggest something else.

huangapple
  • 本文由 发表于 2023年6月29日 21:26:50
  • 转载请务必保留本文链接:https://go.coder-hub.com/76581510.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定