加载后跳转至锚点

15

这个想法

我有一个用户手册页面,内容比较丰富,每个主题都有一个锚链接。

在我的产品页面中,我可以使用锚点直接将客户连接到手册中的某个主题,例如:

手册:

<a href="#manage_options">Managing Options</a>
<!-- Instructions on how to manage options -->

产品页面:

<a href="http://example.com/manual/#!/manage_options">How to Manage Options</a>

问题

当我在产品页面点击"如何管理选项"链接时,它跳转到手册并立即跳转到#manage_options锚点。

但它经常停留在错误的位置,因为它首先跳转到锚点,然后继续加载图像,这会改变内容的位置。

是否有可能等待所有内容加载完成后再跳转到锚点,或者有更好的解决方法吗?

4个回答

6

...它不断地加载图片,这会改变内容的位置。

最佳实践是显式声明图像大小,以避免不必要的重绘:

https://developers.google.com/speed/docs/best-practices/rendering#SpecifyImageDimensions


指定图像尺寸

概述

为所有图像指定宽度和高度可以通过消除不必要的回流和重绘来加快渲染速度。

详情

当浏览器布局页面时,需要能够环绕替换元素(如图像)进行流动。即使在下载图像之前,只要它知道包含非可替换元素的尺寸,就可以开始呈现页面。如果未在包含文档中指定尺寸,或者指定的尺寸与实际图像的尺寸不匹配,则浏览器将在下载图像后需要重新流动和重绘。为了防止回流,请在HTML标签或CSS中指定所有图像的宽度和高度。

建议

指定与图像本身相匹配的尺寸。不要使用宽度和高度规格来动态缩放图像。如果一个图像文件实际上是60 x 60像素,请不要在HTML或CSS中将尺寸设置为30 x 30。如果图像需要变小,请在图像编辑器中缩放它并设置其尺寸以匹配(请参阅优化图像的详细信息)。一定要在图像元素或块级父元素上指定尺寸。一定要在元素本身或块级父元素上设置尺寸。如果父元素不是块级元素,则尺寸将被忽略。不要在祖先元素上设置尺寸,除非它是直接父元素。

所以使用:

<img src="cat.jpg" alt="A Cat" width="360" height="200">

或者

<img src="cat.jpg" alt="A Cat" style="width:360px;height:200px;">

您可以在外部样式表中指定尺寸,但是由于图片尺寸不同,这通常更加困难。这将确保当图片加载时,您的内容不会发生移动。


1
太好了,一个简单的解决方案解决了80%的问题!现在我还有一个问题=>当页面加载完成后,如何防止页面滚动回顶部?(通常是访问者的第一次访问)这可能吗? - Lucas Bustamante
你是通过 AJAX 加载内容吗?从 #!/manage_options 的样子来看似乎是这样,否则你能解释一下 !/ 部分吗?我不确定为什么它会滚动回顶部,但通常在拦截点击的函数中需要使用 return falseevent.preventDefault()。那可能就是你的问题 - 它正在寻找名为 !/manage_options 的锚点,但没有找到,因此像 <a href="#doesnt_exist">This</a> 一样跳转到页面顶部。 - Wesley Murch
我们使用完全相同的结构,Documenter 1.6 => http://docs.revaxarts.com/doc_5abc94922c2f61e83ddda2d5e7112179/ - Lucas Bustamante
我不明白为什么要使用哈希符号 #!,它实际上会改变 URL http://domain/etc/#sources_and_credits 一旦页面加载完成后就会变成哈希符号版本(你甚至可以前进几步,然后点击返回到原始 URL)。也许我错过了什么,但我认为这是毫无意义的虚荣(Twitter 这样做,肯定是好的等等)。无论如何,你尝试在链接上使用 return false 了吗?那个页面并没有像你说的那样跳到顶部。也许需要看更多的代码。 - Wesley Murch
更好的是,我们制作了这个超重版本以更好地说明:http://docs.revaxarts.com/doc_ead50d6febb1d23c9d4bc5d1d5b176bb/#sources_and_credits - Lucas Bustamante
显示剩余2条评论

5
您可以使用 JQuery 脚本解决此问题,它可以在页面加载后延迟锚链接。我还添加了一个偏移量为 20 像素。
$(document).ready(function() {
    if(window.location.hash) {
        $('html, body').animate({
            scrollTop: $(window.location.hash).offset().top - 20
        }, 500);
    }
});

1
没有使用 JQuery 可以实现吗? - Notinlist
1
document.getElementById(window.location.hash.substring(1)).scrollIntoView(); https://developer.mozilla.org/zh-CN/docs/Web/API/Element/scrollIntoView - chimeraha

1

0
@boxed的答案在我在开发者工具控制台中执行代码时非常有效,但是在没有开发者工具的情况下运行代码时却不起作用。我不知道为什么。
@zod的答案更棒(带有平滑效果)。唯一的注意事项是它使用了jQuery。所以我稍微修改了一下,不使用jQuery进行测试,结果非常好!
核心代码如下:
const urlHash = window.location.hash;

if (urlHash) {
    const targetElement = document.querySelector(decodeURI(window.location.hash));

    if (targetElement) {
        var offset = 20;
        var targetOffset = targetElement.getBoundingClientRect().top + window.scrollY;
                
        window.scrollTo({
            top: targetOffset - offset,
            behavior: 'smooth' // 实现平滑滚动.   
        });
    }
}

@chimeraha的评论也是有效的,但最好添加一个decodeURI来使非ASCII哈希值正常工作。
- document.getElementById(window.location.hash.substring(1)).scrollIntoView();
+ document.getElementById(decodeURI(window.location.hash.substring(1))).scrollIntoView();

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接