在我的项目开发过程中,我遇到了一个问题,这与调试期间有和没有预防性断点的getBoundingClientRect值之间的差异有关。为了尽量减少复制,我得到了跟踪。
const scrollHandler = () => {
setTimeout(() => {
const top = document.getElementById('test').getBoundingClientRect().top;
console.log(top);
});
};
document.getElementById('viewport').addEventListener('scroll', scrollHandler);其中viewport只是固定高度的可滚动div。viewport的内容足够大,至少可以触发一个滚动事件。我还创建了柱塞演示。所有魔法都发生在setTimeout回调中。
现在是台阶。成功的情景。
setTimeout回调开始时设置断点。top值。document.getElementById('test').getBoundingClientRect().top。失败的场景。
setTimeout回调结束时设置断点。top变量的值(不需要任何操作)。document.getElementById('test').getBoundingClientRect().top。为了避免对此复制产生任何误解,我用上述步骤录制了一个短片演示电影。
在我的项目中,我在类似的环境(节流滚动事件)中进行计算,得到与预期不符的错误结果。但是当我调试它时,我得到了不同的画面;一个预防性的断点修正了计算。
这是一个bug还是已知的问题?还是我错过了什么?在这种情况下,我应该拒绝使用getBoundingClientRect吗?
发布于 2018-02-08 16:54:37
我不知道你想要的是什么,但假设你的滚动动画不像预期的那样工作。
有一个关于节流卷轴这里的提示是不正确的。假设你每隔30毫秒节流一次。如果页面在上一次动画之后停止滚动25毫秒,那么在它停止滚动之前,您将被困在滚动位置25毫秒内。
也许更好的方法是这样做(可以在本页的控制台中进行测试):
var ol = document.querySelectorAll("ol")[2];
window.onscroll = ((lastExecuted)=>{
const expensiveHandler = e => {
lastExecuted=Date.now();
//do some animation maybe with requestAnimationFrame
// it may prevent overloading but could make animation
// glitchy if system is busy
console.log("1:",ol.getBoundingClientRect().top);
};
var timerID
return e=>{
if(Date.now()-lastExecuted>19){
//only animate once every 20 milliseconds
clearTimeout(timerID);
expensiveHandler(e);
}else{
//make sure the last scroll event does the right animation
// delay of 20 milliseconds
console.log("nope")
clearTimeout(timerID);//only the last is needed
timerID=setTimeout(e=>expensiveHandler(e),20);
}
}
})(Date.now())https://stackoverflow.com/questions/48688505
复制相似问题