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

确定Javascript中垂直滚动百分比的跨浏览器方法,javascript,cross-browser,scroll,Javascript,Cross Browser,Scroll,如何找出用户在任何给定点移动的垂直滚动条的百分比 当用户向下滚动页面时,捕获要触发的onscroll事件很容易,但是如何在该事件中找出他们滚动了多远?在这种情况下,百分比尤其重要。我并不特别担心IE6的解决方案 是否有任何主要框架(Dojo、jQuery、Prototype、Mootools)以简单的跨浏览器兼容方式公开了这一点?使用jQuery $(window).scrollTop(); 将获得滚动位置,然后根据窗口高度计算出百分比 还有一个标准的DOM属性scrollTop,您可以像do

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

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

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

使用jQuery

$(window).scrollTop();
将获得滚动位置,然后根据窗口高度计算出百分比


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

这应该可以做到,不需要库:

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

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

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

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

我知道这个问题已经存在很长时间了,但我在试图解决相同的问题时偶然发现了它。下面是我如何在jQuery中解决它的:

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

<div class="content-wrapper" style="overflow: scroll; height:100px">
    <div class="content">Lot of content that scrolls</div>
</div>
下面是一个工作示例:

2016年10月:固定。答案中缺少jsbin演示中的括号。哎呀

Chrome、Firefox、IE9+。 作为功能: 如果您喜欢
jQuery
(原始答案):
$(窗口).on('scroll',function(){
var s=$(窗口).scrollTop(),
d=$(文档).height(),
c=$(window.height();
var百分比=(s/(d-c))*100;
console.clear();
console.log(滚动百分比);
})
html{height:100%;}
车身{高度:300%;}

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

/**
*获取当前浏览器视图窗格高度
*/
函数_get_window_height(){
返回窗口。内部高度| |
document.documentElement.clientHeight||
document.body.clientHeight | | 0;
}
/**
*获取当前绝对窗口滚动位置
*/
函数_get_window_Yscroll(){
返回窗口。页面偏移量| |
document.body.scrollTop||
document.documentElement.scrollTop | | 0;
}
/**
*获取当前绝对文档高度
*/
函数_get_doc_height(){
返回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_scroll_percentage(){
返回(
(\u get\u window\u Yscroll()+\u get\u window\u height())/\u get\u doc\u height()
) * 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;
    }

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

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

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

yourDocument.addEventListener("scroll", documentEventListener, false);
然后:


类型脚本实现

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);
}

我的两分钱,以一种更“现代”的方式被接受的答案。使用@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`);
});

window height将返回窗口的高度(例如,对于标准分辨率为768px)还是内容的高度(根据页面中的文本量而变化)。window.height将返回视口的高度,document.height将返回内容的高度。刚刚在IE中测试了这些,但没有成功,但是$(document).height()可以跨浏览器使用。如果您在Safari中收缩以展开页面,则此操作不起作用。它会被乘以一个与缩放级别不直接对应的数字。这很接近,谢谢。但是,至少在Chrome中,document.documentElement.scrollHeight和document.documentElement.clientHeight都等于相同的值(内容的高度),因此分母始终为零。啊,是的:现在编辑代码,试试看!WebKit浏览器中有一个奇怪的问题,请参见此处:仍然没有工作:/I我很确定错误在分区的下半部分。(document.documentElement.scrollHeight-document.documentElement.clientHeight)在Chrome中始终等于零。好像是个bug?嗯,刚刚测试过,在Chrome、IE和Firefox中都能正常工作。您使用的是官方最新版本的Chrome吗?Chrome 5.0.335.1 beta版。问题显然是分母的计算结果为零,因为函数(与复制和粘贴的结果完全相同)总是返回无穷大:/因为同一天的其他函数没有给出完整的答案,而每一个其他答案都是在我将其标记为正确的一年多后出现的:)@majelbstoat如果您现在认为另一个更好,移动支票没有什么问题。“好问题维护是好的。”纯Javascript中的完美答案。。!我尝试了其他解决方案,但这只对我非常有效,感谢此解决方案没有给出0%-100%的结果,因为它在开始时添加了视口高度,要使其为0-100,您应该从文档总高度中减去高度:_get_window_Yscroll()/(_get_doc_height()-_get_window_height())@CaioVertematti这就是目标。它显示了用户看到的页面总数的多少。如果用户没有滚动,但整个页面适合视口,则显示100。理论上,如果页面很长和/或视口很短,它可以为您提供0。我已经添加了一个带有live demo的最佳IE9+版本,并恢复了原始的jQuery解决方案。对我来说,它在Chrome上起到了一定的作用,但在最新的Firefox上也不起作用。它给了南。我是推荐人
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+"%");
}
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);
}
// 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`);
});