0

背景

我正在创建一个单页网站。它几乎完成了,而且效果惊人!但是有一个错误我永远无法修复。当单击支持的锚点(链接到某个部分)时,我将滚动到该部分,而不是重新加载页面。

如果该部分已经加载,它会正常滚动到该部分。 在此处输入图像描述

如果未加载,则将请求排队等待稍后。这是发生错误的时候。 在此处输入图像描述 它不是滚动到主页,而是在它的下方滚动。如果请求投资组合,它会向上滚动一半。

重现步骤

假设我继续从事这个设计,可以在我的网站上查看:https ://cjloewen.ca/ 。

  1. 刷新页面。出于测试目的,部分不会加载 10 秒。
  2. 加载时,可以请求任何部分。如果该部分当前未加载,链接旁边将显示加载图标。
  3. 加载请求的部分后,加载将停止,它将等待用户停止滚动,然后使用 滚动到请求的部分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' });

任何帮助是极大的赞赏!

4

0 回答 0