繁体   English   中英

在 Javascript 中确定垂直滚动百分比的跨浏览器方法

[英]Cross-Browser Method to Determine Vertical Scroll Percentage in Javascript

如何找出用户在任何给定点移动的垂直滚动条的百分比?

当用户向下滚动页面时触发onscroll事件很容易,但是我如何在该事件中找出他们滚动了多远? 在这种情况下,百分比尤其重要。 我并不特别担心 IE6 的解决方案。

是否有任何主要框架(Dojo、jQuery、Prototype、Mootools)以简单的跨浏览器兼容方式公开这一点?

2016 年 10 月:已修复。 答案中缺少 jsbin 演示中的括号。 哎呀。

铬、火狐、IE9+。 jsbin 上的现场演示

var h = document.documentElement, 
    b = document.body,
    st = 'scrollTop',
    sh = 'scrollHeight';

var percent = (h[st]||b[st]) / ((h[sh]||b[sh]) - h.clientHeight) * 100;

作为功​​能:

function getScrollPercent() {
    var h = document.documentElement, 
        b = document.body,
        st = 'scrollTop',
        sh = 'scrollHeight';
    return (h[st]||b[st]) / ((h[sh]||b[sh]) - h.clientHeight) * 100;
}

如果您更喜欢jQuery (原始答案):

 $(window).on('scroll', function(){ var s = $(window).scrollTop(), d = $(document).height(), c = $(window).height(); var scrollPercent = (s / (d - c)) * 100; console.clear(); console.log(scrollPercent); })
 html{ height:100%; } body{ height:300%; }
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

我想我找到了一个不依赖于任何库的好解决方案:

/**
 * Get current browser viewpane heigtht
 */
function _get_window_height() {
    return window.innerHeight || 
           document.documentElement.clientHeight ||
           document.body.clientHeight || 0;
}

/**
 * Get current absolute window scroll position
 */
function _get_window_Yscroll() {
    return window.pageYOffset || 
           document.body.scrollTop ||
           document.documentElement.scrollTop || 0;
}

/**
 * Get current absolute document height
 */
function _get_doc_height() {
    return Math.max(
        document.body.scrollHeight || 0, 
        document.documentElement.scrollHeight || 0,
        document.body.offsetHeight || 0, 
        document.documentElement.offsetHeight || 0,
        document.body.clientHeight || 0, 
        document.documentElement.clientHeight || 0
    );
}


/**
 * Get current vertical scroll percentage
 */
function _get_scroll_percentage() {
    return (
        (_get_window_Yscroll() + _get_window_height()) / _get_doc_height()
    ) * 100;
}

这应该可以解决问题,不需要库:

function currentScrollPercentage()
{
    return ((document.documentElement.scrollTop + document.body.scrollTop) / (document.documentElement.scrollHeight - document.documentElement.clientHeight) * 100);
}

这些在 Chrome 19.0、FF12、IE9 中对我来说非常有效:

function getElementScrollScale(domElement){
        return domElement.scrollTop / (domElement.scrollHeight - domElement.clientHeight);
    }

function setElementScrollScale(domElement,scale){
        domElement.scrollTop = (domElement.scrollHeight - domElement.clientHeight) * scale;
    }

如果您使用的是 Dojo,则可以执行以下操作:

var vp = dijit.getViewport();
return (vp.t / (document.documentElement.scrollHeight - vp.h));

这将返回一个介于 0 和 1 之间的值。

一个打字稿实现。

function getScrollPercent(event: Event): number {
  const {target} = event;
  const {documentElement, body} = target as Document;
  const {scrollTop: documentElementScrollTop, scrollHeight: documentElementScrollHeight, clientHeight} = documentElement;
  const {scrollTop: bodyScrollTop, scrollHeight: bodyScrollHeight} = body;
  const percent = (documentElementScrollTop || bodyScrollTop) / ((documentElementScrollHeight || bodyScrollHeight) - clientHeight) * 100;
  return Math.ceil(percent);
}

我知道这个问题已经存在很长时间了,但是我在尝试解决同样的问题时偶然发现了它。 这是我在 jQuery 中解决它的方法:

首先,我将我想要滚动的内容包装在一个 div 中(不是语义,但它有帮助)。 然后在包装纸上设置溢出和高度。

<div class="content-wrapper" style="overflow: scroll; height:100px">
    <div class="content">Lot of content that scrolls</div>
</div>

最后,我能够根据这些指标计算滚动百分比:

var $w = $(this),
    scroll_top = $w.scrollTop(),
    total_height = $w.find(".content").height(),        
    viewable_area = $w.height(),
    scroll_percent = Math.floor((scroll_top + viewable_area) / total_height * 100);                

这是一个带有工作示例的小提琴: http : //jsfiddle.net/prEGf/

每个人都有很好的答案,但我只需要一个答案作为一个变量。 我不需要事件监听器,我只是想获得滚动百分比。 这就是我得到的:

const scrolledPercentage = 
    window.scrollY / (document.documentElement.scrollHeight - document.documentElement.clientHeight)

 document.addEventListener("scroll", function() { const height = window.scrollY / (document.documentElement.scrollHeight - document.documentElement.clientHeight) document.getElementById("height").innerHTML = `Height: ${height}` })
 .container { position: relative; height: 200vh; }.sticky-div { position: sticky; top: 0; }
 <:DOCType> <html> <head> </head> <body> <div id="container" class="container"> <div id="height" class="sticky-div"> Height: 0 </div> </div> </body>

首先将事件侦听器附加到要跟踪的某个文档

yourDocument.addEventListener("scroll", documentEventListener, false);

然后:

function documentEventListener(){
  var currentDocument  = this;
  var docsWindow       = $(currentDocument.defaultView); // This is the window holding the document
  var docsWindowHeight = docsWindow.height(); // The viewport of the wrapper window
  var scrollTop        = $(currentDocument).scrollTop(); // How much we scrolled already, in the viewport
  var docHeight        = $(currentDocument).height();    // This is the full document height.

  var howMuchMoreWeCanScrollDown = docHeight - (docsWindowHeight + scrollTop);
  var percentViewed = 100.0 * (1 - howMuchMoreWeCanScrollDown / docHeight);
  console.log("More to scroll: "+howMuchMoreWeCanScrollDown+"pixels. Percent Viewed: "+percentViewed+"%");
}

我的两分钱,以更“现代”的方式接受的答案。 使用@babel/preset-env返回到 IE9。

// utilities.js

/**
 * @param {Function} onRatioChange The callback when the scroll ratio changes
 */
export const monitorScroll = onRatioChange => {
  const html = document.documentElement;
  const body = document.body;

  window.addEventListener('scroll', () => {
    onRatioChange(
      (html.scrollTop || body.scrollTop)
      /
      ((html.scrollHeight || body.scrollHeight) - html.clientHeight)
    );
  });
};

用法:

// app.js
import { monitorScroll } from './utilities';

monitorScroll(ratio => {
  console.log(`${(ratio * 100).toFixed(2)}% of the page`);
});

我在那里回顾了所有这些,但他们使用更复杂的方法来解决。 我通过一个数学公式发现了这一点; 简短的。

公式为 Value/Total * 100。假设 Total 是 200 你想知道 200 中 100 的百分比,你可以做到 100/200 * 100% = 50%(价值)

pageYOffset = 不包括边框的垂直滚动计数。 当您向下滚动到底部时,您将获得最大计数。 offsetHeight = 页面的总高度,包括边框! clientHeight = 以像素为单位的高度,没有边框,但不是到内容的末尾!

例如,当您滚动到底部时,您的 pageyoffset 为 1000,而 offsetHeight 为 1200,clientHeight 为 200. 1200 - 200(clientheight) 现在您在 offsetHeight 中获得 pageyOffset 值,因此 scrollPosition300(300 of 1000)/1000 * 100 = 30% .

`pageOffset = window.pageYOffset; pageHeight = document.documentElement.offsetHeight; clientHeight = document.documentElement.clientHeight;

percentage = pageOffset / (pageHeight - clientHeight) * 100 + "%";
console.log(percentage)`

之所以必须做offsetHeight-clientHeight,是因为client heights显示了px中所有可用的内容,没有边框,offsetheight显示了包括边框在内的可用内容,而pageYOffset计算了所做的滚动; 滚动条很长,无法计算整个 windows 它会计算滚动本身直到到达末尾,滚动条中的可用空间以 px pageYOffset 为单位,因此要达到该数字,请减去 offsetHeight - clientHeight 以降低 pageYOffset 的值。

我会在我上电脑时更新,请留下评论以说明清楚,以免我忘记:谢谢 :)

使用 jQuery

$(window).scrollTop();

将为您提供滚动位置,然后您可以从那里计算出基于窗口高度的百分比。

还有一个标准的 DOM 属性scrollTop可以像document.body.scrollTop一样使用,但是我不确定它是如何跨浏览器的,我会假设如果存在不一致,那么 jQuery 方法会解释这些。

var maxScrollTop = messages.get(0).scrollHeight - messages.height();
var scroll = messages.scrollTop() / maxScrollTop; // [0..1]

我找到了一种方法来纠正以前的答案,因此它适用于所有情况。 在 Chrome、Firefox 和 Safari 上测试。

(((document.documentElement.scrollTop + document.body.scrollTop) / (document.documentElement.scrollHeight - document.documentElement.clientHeight) || 0) * 100)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM