我对编程比较陌生,正在开发一个带弹出窗口的Chrome扩展程序。我想在弹出调用之间保存滚动位置。好像我在互联网上发现了很多信息,但到目前为止我还没能解决我的问题。保存滚动位置几乎适用于我的扩展程序,但我看到2个问题:
1)要在每个滚动事件中保存滚动位置,我使用:
addEventListener('scroll', function(){
localStorage.scrollTop = document.body.scrollTop;
});
打开弹出窗口时,我使用:
document.body.scrollTop = localStorage.scrollTop
这似乎工作正常,直到我的滚动位置超过弹出高度。 Chrome扩展程序中可见内容的最大弹出窗口高度为600px。 document.body.style.height
也始终是大于600px的固定值。当滚动位置大于document.body.style.height
- 600px,比如900px - 600px时,document.body.scrollTop
将重置为300px。即使最后一个滚动位置(document.body.scrollTop
)在弹出窗口关闭之前是400px,当重新打开弹出窗口时,滚动位置也会重置为300px。显然,我得到错误的滚动位置,因为正确的滚动位置值400px(例如)被300px覆盖。
然而,并非总是如此。有时我可以正确保存滚动位置,例如500px,窗口高度为900px,有时我不能。我不确定为什么会产生任何影响,但由于弹出窗口中的内容较高,问题似乎神奇地消失了,保存了正确的滚动位置。
在这种情况下,如何在滚动位置时正确保存滚动位置?也许我在做一些根本错误的事情?
(这看起来很混乱。我希望可以帮助解决上面的代码。)
2)我认为可能与上述问题交织在一起,但我不确定。对于每个滚动事件(本文中的第一个代码块),我看到一对滚动事件被触发。
如果我只是打开弹出窗口但不滚动鼠标滚轮,我会在事件监听器内部看到代码。当第一个事件发生时,document.body.scrollTop
将重置为“错误”值(上例中为300px)。我认为这可能是两个问题的根本原因。
如果移动鼠标滚轮,事件监听器不应该只触发,因此如果打开弹出窗口但未触摸鼠标滚轮,则事件监听器内的代码不会执行?
答案 0 :(得分:3)
问题实际上是在相应的CSS代码中。 <div>
不可滚动,因此不允许保存大于弹出窗口可见区域的滚动位置。
解决方案是将position: relative;
和overflow-y: auto;
(overflow-y: scroll;
也适用)属性添加到CSS元素中。
添加这些属性后,我可以将滚动位置正确保存到对象。
答案 1 :(得分:0)
我知道这不应该是一个答案,但我不能在评论中格式化代码:
我打算走出困境并建议你尝试测试一个基本假设:滚动事件是否按顺序触发?
试试这个,看看是否添加了一些有用的调试信息:
var scrollCounter = 0;
addEventListener('scroll', function(){
localStorage.scrollTop = document.body.scrollTop;
console.log({counter: scrollCounter, scrollTop: document.body.scrollTop});
scrollCounter++
})
查看这些数字是否会跳跃,或者它们是否按顺序排列。
编辑:可能解决方案的P代码
我想我对fix
有一个想法,虽然我在这里松散地使用了修复这个词。
var captureSemaphore; // Use this to flag exactly when we want the `scrollTop` captured.
captureSemaphore = true; // Go into catch mode
addEventListener('scroll', function(){
if (captureSemaphore) {
localStorage.scrollTop = document.body.scrollTop;
}
});
// then later, right before you open your popup
captureSemaphore = false; // Disable catch mode because the screen is about to change
openPopup(); // Open the popup
// Elsewhere
closePopup(); // Close the popup
captureSemaphore = true; // Go into catch mode