进度条脚本从jQuery转原生JS:计算值不符问题求助
解决原生JS滚动进度条数值不一致的问题
首先,我帮你拆解原jQuery代码的逻辑,然后对应到原生JS的正确写法——问题通常出在文档高度、视口高度和滚动距离的获取方式上,下面是详细的解决方案:
原jQuery逻辑回顾
先把你给出的核心代码整理清楚,方便对比:
$(document).scroll(function() { var progressBar = $('progress'), docHeight = $(this).height(), // 文档总高度 winHeight = $(window).height(), // 浏览器视口高度 max = docHeight - winHeight, // 滚动的最大可移动距离(滚动到底部时的scrollTop值) value = $(window).scrollTop(); // 当前滚动距离 progressBar.attr('max', max); progressBar.attr('value', value); });
原生JS的正确实现
下面是和jQuery逻辑完全一致的原生代码,我会标注每个部分对应的jQuery写法,以及容易踩坑的点:
document.addEventListener('scroll', function() { // 对应 $('progress'),找不到元素时提前返回避免报错 const progressBar = document.querySelector('progress'); if (!progressBar) return; // 对应 $(document).height():jQuery取的是文档总滚动高度,原生需兼容两种DOM节点的取值 const docHeight = Math.max(document.body.scrollHeight, document.documentElement.scrollHeight); // 对应 $(window).height():原生直接用window.innerHeight即可 const winHeight = window.innerHeight; // 滚动最大距离,逻辑和jQuery完全一致 const max = docHeight - winHeight; // 对应 $(window).scrollTop():window.pageYOffset是兼容所有浏览器的写法 const value = window.pageYOffset; // 对应 attr('max', max):progress元素的max是原生属性,直接赋值更高效 progressBar.max = max; // 对应 attr('value', value):同理直接操作原生value属性 progressBar.value = value; });
为什么你的原生代码数值不对?
大概率是这几个地方踩了坑:
- 文档高度获取错误:如果只写
document.body.scrollHeight,在某些浏览器或特殊页面布局下(比如设置了html的高度样式),会得到错误的数值,必须取body和documentElement的最大值,才能和jQuery的逻辑对齐。 - 滚动距离获取错误:不要用
document.body.scrollTop,标准模式下滚动距离存在于document.documentElement.scrollTop,而window.pageYOffset是兼容所有场景的写法,和jQuery的$(window).scrollTop()完全一致。 - 错误使用setAttribute:虽然
progressBar.setAttribute('max', max)也能生效,但直接赋值progressBar.max更贴合jQuery修改原生属性的逻辑,也更高效。
额外优化建议
可以给滚动事件加防抖,避免页面滚动时频繁触发计算,提升性能:
let scrollTimer; document.addEventListener('scroll', function() { clearTimeout(scrollTimer); scrollTimer = setTimeout(function() { // 把上面的计算逻辑放在这里 const progressBar = document.querySelector('progress'); if (!progressBar) return; const docHeight = Math.max(document.body.scrollHeight, document.documentElement.scrollHeight); const winHeight = window.innerHeight; const max = docHeight - winHeight; const value = window.pageYOffset; progressBar.max = max; progressBar.value = value; }, 10); });
内容的提问来源于stack exchange,提问作者Joe278
相关产品推荐
相关产品推荐

