背景
我正在创建一个单页网站。它几乎完成了,而且效果惊人!但是有一个错误我永远无法修复。当单击支持的锚点(链接到某个部分)时,我将滚动到该部分,而不是重新加载页面。
如果未加载,则将请求排队等待稍后。这是发生错误的时候。 它不是滚动到主页,而是在它的下方滚动。如果请求投资组合,它会向上滚动一半。
重现步骤
假设我继续从事这个设计,可以在我的网站上查看:https ://cjloewen.ca/ 。
- 刷新页面。出于测试目的,部分不会加载 10 秒。
- 加载时,可以请求任何部分。如果该部分当前未加载,链接旁边将显示加载图标。
- 加载请求的部分后,加载将停止,它将等待用户停止滚动,然后使用 滚动到请求的部分
elem.scrollIntoView({ behavior: 'smooth', block: 'start' });
。
我试过的
- 我已经验证它正在滚动到正确的元素,并且没有其他元素。
- 我切换到使用 MutationObserver 来了解元素何时添加到 DOM。
- 我尝试在滚动之前等待 requestAnimationFrame 。
- 我尝试在滚动之前添加一个短暂的 500 毫秒超时。
- 我尝试在滚动之前添加 60 秒超时,以确保我在任何时候都没有与页面交互。
- 我尝试使用 scrollTo 而不是 scrollIntoView 滚动(相同的行为)。
- 我在 Edge 中尝试过(行为略有不同但问题相同)。
源代码
所有相关的源代码都可以在https://cjloewen.ca/js/main.js找到(包括源图)。
- 我在第 156 行插入部分。
previous.before(next)
previous.after(next)
- 我在第 80 行锁定加载。
// Set the lock.
mainContentLockWaiting = [];
mainContentLock = true;
// ...
// Reset the lock.
mainContentLock = false;
for (let insert of mainContentLockWaiting)
insert();
- 我在第 84 行等待用户停止滚动。
let isScrolling = null;
let scrollListener = function() {
clearTimeout(isScrolling);
isScrolling = setTimeout(function() {
mainContent.removeEventListener('scroll', scrollListener);
resolve();
}, 250);
}
mainContent.addEventListener('scroll', scrollListener, false);
- 在第 73 行调用 scrollIntoView。
elem.scrollIntoView({ behavior: 'smooth', block: 'start' });
任何帮助是极大的赞赏!