最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Fractional scrollHeight? - Stack Overflow

programmeradmin9浏览0评论

.scrollHeight:

This property will round the value to an integer. If you need a fractional value, use element.getBoundingClientRect().

Except... element.getBoundingClientRect() does not return the scrollHeight. How would one get a fractional scrollHeight? Is it possible?

https://developer.mozilla/en-US/docs/Web/API/element.scrollHeight:

This property will round the value to an integer. If you need a fractional value, use element.getBoundingClientRect().

Except... element.getBoundingClientRect() does not return the scrollHeight. How would one get a fractional scrollHeight? Is it possible?

Share Improve this question edited Aug 16, 2018 at 7:35 ThomasR 1,1351 gold badge12 silver badges17 bronze badges asked Feb 10, 2014 at 0:01 AgamemnusAgamemnus 1,4464 gold badges20 silver badges44 bronze badges
Add a ment  | 

3 Answers 3

Reset to default 0

Inside the scrollable outerEl, have an innerEl element contain all content, so the scrollHeight equals the element height. Then you can get scroll height in decimals using innerEl.getBoundingClientRect().height.

Note that you need to make sure there is no margin between outerEl and innerEl. Set padding of outerEl to 0, margin of innerEl, first child of innerEl, and last child of innerEl to 0.

document.getElementById("scrollHeight").innerText = document.getElementById("outer").scrollHeight
document.getElementById("boundingRect").innerText = document.getElementById("inner").getBoundingClientRect().height
#outer {
  height: 50px;
  overflow-y: auto;
  background-color: lightblue;
  padding: 0px;
}

#inner {
  margin: 0;
  background-color: yellow;
}

.content {
  margin: 0;
}
<div id="outer">
  <div id="inner">
    <div class="content">
      outerEl.scrollHeight: <span id="scrollHeight">?</span>
    </div>
    <div class="content">
      innerEl.getBoundingClientRect().height: <span id="boundingRect">?</span>
    </div>
    <div class="content">
      You must make sure there is no margin between outer element and inner element.
    </div>
  </div>
</div>

This will get the diff between the integer and floating width by paring clientWidth to rect.width, and then applying that to scrollWidth. It also takes into account issues with subtracting floating point numbers in javascript, and if a scrollbar is present.

function getScrollWidth(el) {
    return getScrollDimension(el, true);
}
function getScrollHeight(el) {
    return getScrollDimension(el, false);
}

function getScrollDimension(el, isWidth) {
    // https://stackoverflow./questions/21666892/fractional-scrollheight
    // https://stackoverflow./questions/6027937/javascript-float-subtract

    const rect = el.getBoundingClientRect();
    const rectVal = isWidth ? rect.width : rect.height;
    const clientVal = isWidth ? el.clientWidth : el.clientHeight;
    const scrollVal = isWidth ? el.scrollWidth : el.scrollHeight;
    const offsetVal = isWidth ? el.offsetWidth : el.offsetHeight;

    const oppositeScrollbarVal = offsetVal - clientVal; // when measuring width, this is the vertical scrollbar width

    const dimString = rectVal.toString();
    const decimalIndex = dimString.indexOf(".");
    let decimalPlaces = 0;
    if (decimalIndex > -1) {
        decimalPlaces = dimString.substr(decimalIndex + 1).length;
    }
    
    const multiplier = Math.pow(10, decimalPlaces); // get us out of floating point math to avoid rounding errors

    // rect.width and e.clientWidth are the same measurement, but rect.width has more precision because el.clientWidth is rounded.
    // Get the difference between those and apply it to the scrollWidth.
    // 
    // If el.clientWidth was rounded down from 100.4 to 100, then we want to end up with 0.4.
    // If el.clientWidth was rounded up from 100.5 to 101, then we want to end up with -0.5.
    const diff = ((rectVal * multiplier) - (clientVal * multiplier)) ; 

    const finalScrollWidth = ((scrollVal * multiplier) + (diff)) / multiplier;
    return finalScrollWidth - oppositeScrollbarVal;
}

I think I might have the solution:

var rect = element.getBoundingClientRect()
var scrollHeight = element.scrollHeight + (parseInt(rect.height) - rect.height)
var scrollWidth  = element.scrollWidth  + (parseInt(rect.width)  - rect.width)
发布评论

评论列表(0)

  1. 暂无评论