在动态生成的页面上可靠地跳转到命名锚点?

问题描述 投票:0回答:4

我有一个由客户端动态构建的网页。它生成数十个列表项,每个列表项都有自己的命名锚点。页面的一侧有一个固定的目录 (TOC),其中包含指向指定锚点的超链接。这允许用户单击目录条目跳转到该项目。

我遇到的麻烦是,在初始页面加载时,页面是动态生成的,因此它无法使用浏览器的默认行为滚动到 URL 的初始哈希中的项目。此外,当用户切换到另一本书时,页面将完全重新生成,并包含新内容和新的起始哈希值。同样的问题:由于哈希值预先存在内容,因此它不会将自己定位在已在视图中的项目中。

我几乎用 JavaScript 解决了这个问题,方法是等待渲染,然后在适当的元素上使用

scrollIntoView
方法跳转到哈希。

下一个问题是,在调用

scrollIntoView
时,样式表尚未完全应用,因此项目的最终位置未知。我看到未样式化的项目滚动到视图中,但是一旦应用样式,定位就会丢失。我放置了 1 秒
setTimeout
来延迟
scrollIntoView
调用。这有效,但感觉很脆弱。

当哈希值到位后内容出现时,是否有可靠的技术可以跳转到指定锚点?如果我知道 CSS 何时完成样式化内容可能会有所帮助。或者,一旦页面高度稳定(从而发出 CSS 样式的最终确定信号),触发事件可能会很有用。

javascript css anchor
4个回答
6
投票

我遇到了类似的问题,尽管在我的情况下,只有目录和命名锚点是在 onload 处理程序中自动生成的 - 而不是页面内容的其余部分。我通过在生成锚点后将以下代码添加到我的 onload 处理程序中解决了初始哈希问题:

if (location.hash)
{
    var requested_hash = location.hash.slice(1);
    location.hash = '';
    location.hash = requested_hash;
}

我必须先将哈希值设置为“”,然后再将其设置回请求的名称以使浏览器做出响应。这似乎适用于我尝试过的所有浏览器(Opera、Chrome、Edge、IE、FF)。


0
投票

我遇到了同样的问题。在文档的 onload 事件触发后,页面的大部分内容都是动态加载的,并且导航到页面上的给定锚点无法正常工作。访问者通常会降落在页面上的“随机”位置,并且预期目标已被文档中之前动态添加的内容推离视口。

这就是我解决的方法:

(function() {
    var targetElement = document.querySelector(window.location.hash);
    if (targetElement) {
        var stayInPlace = function() {
            targetElement.scrollIntoView();
        };
        var observer = new ResizeObserver(stayInPlace);
        var stopObserving = function() {
            observer.disconnect();
        };
        
        observer.observe(document.querySelector('main'));
        window.addEventListener('wheel', stopObserving, {once: true});
        window.addEventListener('touchstart', stopObserving, {once: true});
    }
})();

我正在使用 ResizeObserver API(自 2018 年左右开始提供)来检测

<main>
元素大小的更改。就我而言,目标和动态加载的元素都是主元素的子元素。如果需要的话进行调整。每次尺寸更改时,我们确保将请求的目标滚动到视图中。

每当用户开始使用滚轮或触摸与页面交互时,我们就会停止观察并强制调整滚动位置。我无法弄清楚如何检测滚动条的使用。


-1
投票

如果您始终知道要设置焦点的元素的名称,则可以使用 jQuery。您可以在页面加载后运行此命令:

$( "#targetElementGoesHere" ).focus();

编辑:要滚动到该位置,请查看 https://github.com/flesler/jquery.scrollTo


-1
投票

我认为这个人已经回答了你需要的答案......

如何使用javascript等待网页加载?

所以,像这样...

document.onload = function(){ 
    scrollIntoView...
}
© www.soinside.com 2019 - 2024. All rights reserved.