0

我对编程比较陌生,并且正在开发带有弹出窗口的 Chrome 扩展程序。我想保存弹出调用之间的滚动位置。似乎我在互联网上找到了很多信息,但到目前为止我还没有能够解决我的问题。保存滚动位置几乎可以在我的扩展中使用,但我看到了 2 个问题:

1)要在每个滚动事件中保存滚动位置,我使用:

addEventListener('scroll', function(){
   localStorage.scrollTop = document.body.scrollTop;
});

当弹出窗口打开时,我使用:

document.body.scrollTop = localStorage.scrollTop

这似乎工作正常,直到我的滚动位置超过弹出高度。Chrome 扩展中可见内容的最大弹出高度为 600 像素。document.body.style.height也始终是大于 600px 的固定值。当滚动位置大于document.body.style.height- 600px,比如 900px - 600px,document.body.scrollTop重置为 300px。即使document.body.scrollTop在弹出窗口关闭之前最后滚动位置 ( ) 是 400 像素,当重新打开弹出窗口时,滚动位置也会重置为 300 像素。显然,我得到了错误的滚动位置,因为正确的滚动位置值 400px(例如)然后被 300px 覆盖。

然而,它并不总是发生。有时我可以正确保存滚动位置,例如 500 像素,窗口高度为 900 像素,而其他时候我不能。我不确定为什么这会产生任何影响,但是随着弹出窗口中的内容更高,问题似乎神奇地消失了,并且保存了正确的滚动位置。

在这种情况下滚动位置时如何正确保存滚动位置?也许我在做一些根本错误的事情?

(这似乎令人困惑。我希望可以对上面的代码有所帮助。)

2)我认为可能与上述问题交织在一起,但我不确定。对于每个滚动事件(本文中的第一个代码块),我看到触发了一对滚动事件。

如果我只是打开弹出窗口但不滚动鼠标滚轮,我会看到事件侦听器中的代码触发。当第一个事件发生时,document.body.scrollTop重置为“错误”值(在上面的示例中为 300px)。我认为这可能是这两个问题的根本原因。

事件监听器不应该只在鼠标滚轮被移动时触发,因此如果弹出窗口打开但鼠标滚轮未被触摸,事件监听器内的代码不会执行?

4

2 回答 2

3

问题实际上出在相应的 CSS 代码中。不可滚动,因此<div>它不允许保存大于弹出窗口可见区域的滚动位置。

解决方案是向CSS 元素添加position: relative;and overflow-y: auto;(也可以) 属性。overflow-y: scroll;

添加这些属性后,我可以正确地将滚动位置保存到对象中。

于 2012-11-27T11:19:43.727 回答
0

我知道这不应该是一个答案,但我无法在评论中格式化代码:

我将冒险出去并建议您尝试测试一个基本假设: 滚动事件是否按顺序触发?

试试这个,看看是否添加了一些有用的调试信息:

var scrollCounter = 0;
addEventListener('scroll', function(){
   localStorage.scrollTop = document.body.scrollTop;
   console.log({counter: scrollCounter, scrollTop: document.body.scrollTop});
   scrollCounter++
})

看看这些数字是否似乎在跳跃,或者它们是否按递增顺序排列。

编辑:可能解决方案的 P 代码

我想我对 a 有一个想法fix,尽管我在这里松散地使用了 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
于 2012-09-23T03:58:36.337 回答