The Idea
I have a User Manual page, it is kinda big, and each topic has a anchor linked to it.
我有一个用户手册页面,它有点大,每个主题都有一个链接到它的锚。
In my product page, I can link the client straight to that topic in the manual with a anchor, like:
在我的产品页面中,我可以使用锚点将客户直接链接到手册中的该主题,例如:
Manual:
手册:
<a href="#manage_options">Managing Options</a>
<!-- Instructions on how to manage options -->
Product Page:
产品页:
<a href="http://example.com/manual/#!/manage_options">How to Manage Options</a>
The Problem
When I click the "How to Manage Options" link in Product Page, it goes to the manual and immediately to the #manage_options anchor
当我在产品页面中点击“How to Management Options”链接时,它会转到手册,并立即转到#Manage_Options锚
But it often stops in the wrong place, because it goes to the anchor, then it keeps loading images, which changes the position of the content
但它经常停在错误的位置,因为它转到锚点,然后继续加载图像,这会改变内容的位置
Is it possible to wait for all the content to be loaded, then it goes to the anchor, or any better solution for this problem?
是否可以等待所有内容加载完毕,然后转到锚,或者有什么更好的解决方案?
更多回答
...it keeps loading images, which changes the position of the content
It's a best practice to explicitly declare your image sizes to avoid unnecessary repaints:
最佳做法是明确声明图像大小,以避免不必要的重新绘制:
https://developers.google.com/speed/docs/best-practices/rendering#SpecifyImageDimensions
Https://developers.google.com/speed/docs/best-practices/rendering#SpecifyImageDimensions
Specify image dimensions
Overview
Specifying a width and height for all images allows for faster
rendering by eliminating the need for unnecessary reflows and
repaints.
Details
When the browser lays out the page, it needs to be able to flow around
replaceable elements such as images. It can begin to render a page
even before images are downloaded, provided that it knows the
dimensions to wrap non-replaceable elements around. If no dimensions
are specified in the containing document, or if the dimensions
specified don't match those of the actual images, the browser will
require a reflow and repaint once the images are downloaded. To
prevent reflows, specify the width and height of all images, either in
the HTML tag, or in CSS.
Recommendations
Specify dimensions that match those of the images themselves. Don't
use width and height specifications to scale images on the fly. If an
image file is actually 60 x 60 pixels, don't set the dimensions to 30
x 30 in the HTML or CSS. If the image needs to be smaller, scale it in
an image editor and set its dimensions to match (see Optimize images
for details.) Be sure to specify dimensions on the image element or
block-level parent Be sure to set the dimensions on the element
itself, or a block-level parent. If the parent is not block-level, the
dimensions will be ignored. Do not set dimensions on an ancestor that
is not an immediate parent.
So use:
因此,请使用:
<img src="cat.jpg" alt="A Cat" width="360" height="200">
Or
或
<img src="cat.jpg" alt="A Cat" style="width:360px;height:200px;">
...or you can specify the dimensions in an external stylesheet, but generally that is more difficult with varying image sizes. This will ensure your content doesn't shift as images are loaded.
...或者您可以在外部样式表中指定尺寸,但通常情况下,使用不同的图像大小更难做到这一点。这将确保您的内容在加载图像时不会发生变化。
You can solve the problem using a JQuery script, this can postpone the anchor link after the page is loaded, i added an offset of 20 px also.
你可以使用JQuery脚本解决这个问题,这可以推迟页面加载后的锚链接,我还添加了20px的偏移量。
$(document).ready(function() {
if(window.location.hash) {
$('html, body').animate({
scrollTop: $(window.location.hash).offset().top - 20
}, 500);
}
});
function moveToHash() {
let urlHash = window.location.hash;
if (urlHash) {
window.location.hash = '';
window.location.hash = urlHash;
}
}
(Copied and fixed from https://stackoverflow.com/a/21447965/371908)
(从https://stackoverflow.com/a/21447965/371908)复制和修复
@boxed's answer works excellently when I execute the code in the developer tool console, but it doesn't work when I run from code without the developer tool. I don't know why.
当我在开发人员工具控制台中执行代码时,@boxed的答案工作得很好,但当我在没有开发人员工具的情况下从代码运行时,它就不起作用了。我也不知道原因。
@zod's answer is more fantastic (with smooth effect). The only caveat is it's using jQuery. So I changed it a little without using jQuery and tested it works very well!
@Zod的回答更奇妙(效果流畅)。唯一需要注意的是,它使用的是jQuery。因此,我在没有使用jQuery的情况下对其进行了一些更改,并对其进行了测试,结果非常好!
The core is as follows:
其核心内容如下:
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' // 实现平滑滚动.
});
}
}
The @chimeraha's comment also work, but it's better to add a decodeURI
to make non ASCII hash to work:
@chieraha的注释也起作用,但最好添加一个decdeURI以使非ASCII散列起作用:
- document.getElementById(window.location.hash.substring(1)).scrollIntoView();
+ document.getElementById(decodeURI(window.location.hash.substring(1))).scrollIntoView();
更多回答
Done. That's great, a simple solution that solved 80% of the problem! I have one more issue with it now => How do I prevent the page from scrolling back to TOP when finished loading? (usually in visitor's first visit) Is it possible?
好了。太棒了,一个简单的解决方案就解决了80%的问题!我现在还有一个问题=>如何防止页面在加载完成后滚动回到顶部?(通常是在游客第一次参观时)有可能吗?
Are you loading the content via AJAX? It seems to be the case by the looks of #!/manage_options
, otherwise can you explain the !/
part? I'm not sure I understand why it would be scrolling back to the top, but generally a return false
or event.preventDefault()
is needed in the function that intercepts the click. That's probably your issue - it's looking for an anchor named !/manage_options
and not finding it, therefore jumping to the top of the page as it would with something like <a href="#doesnt_exist">This</a>
.
您是否通过AJAX加载内容?从#!/Manage_Options的外观上看似乎是这样,否则你能解释一下!/部分吗?我不确定我是否理解为什么它会滚动回到顶部,但通常在拦截点击的函数中需要一个返回FALSE或Event.PrementDefault()。这可能就是您的问题--它正在寻找一个名为!/Manage_Options的锚点,但没有找到它,因此跳到页面顶部,就像使用this一样。
I don't get what the point of the hashbang #!
is there, it actually changes the url http://domain/etc/#sources_and_credits into the hashbang version once it loads (you can even go forward a few steps, then click back to get to the original URL). I may be missing something but I think it's pointless vanity (Twitter does it, must be good, etc. etc). Anyways, did you try return false
on the links? That page doesn't jump to the top like you say yours does. Maybe need to see more code.
我不明白这个hashbang有什么意义!加载后,它实际上会将url http://domain/etc/#sources_and_credits更改为hashbang版本(您甚至可以前进几个步骤,然后单击Back以返回原始url)。我可能错过了一些东西,但我认为这是毫无意义的虚荣心(Twitter做到了,一定是好的,等等)。不管怎样,你有没有试着在链接上返回假呢?该页面不会像您所说的那样跳到顶部。也许需要看到更多的代码。
I think it doesn't jump to the top because it is really light, so it loads instantly. Try this: revaxarts-themes.com/documenter/docs/#!/what_else (clear cache if it doesn't bugs at once)
我认为它不会跳到顶部,因为它真的很轻,所以它可以立即加载。试试这个:revaxarts-themes.com/documenter/docs/#!/what_else(如果没有立即出现错误,则清除缓存)
Is it doable without JQuery?
没有JQuery,这行得通吗?
我是一名优秀的程序员,十分优秀!