当这些 URL 是跳转目标时,这个问题是关于让散列 URL(如mydomain.com/somepage#SomeAnchor
)从固定页面标题下滚动出来。这是这个已回答问题的一个分支——但我想知道是否有人得到了完全在 Tripit Slate 文档发布框架上工作的答案?
这个基于 Slate 的网站不是我们的,但它显示了我们的困境:
如果您单击左侧导航中的链接,则中心文本列将滚动到您选择的标题。一切都很好。
但请尝试单击正文中的链接。例如,从 http://buddycloud.com/api#accounts点击
push notification
链接。您滚动到一个完全不同的子标题。您请求的目标实际上具有焦点,但它隐藏在顶部导航栏下方。(向上滚动,你会看到它。)
我们的左导航链接工作干净,就像 buddycloud 网站的一样。感谢Sidnious 的 4086107 回答,我们在所有标题上方放置了一个不可见的伪元素,正如 Nicolas Gallagher 设计的那样。这是 CSS 类:
.jumptarget::before {
content:"";
display:block;
height:85px; /* fixed header height*/
margin:-85px 0 0; /* negative fixed header height */
}
以下是我们如何将其应用于标题:
## <span class="jumptarget" id="SomeAnchorName"> SomeHeading </span>
这对左侧导航很有效。从 css-tricks 中,我们了解了为什么“页内”散列链接仍然失败:
当链接包含哈希时,如下所示:
<a href="#section-two">Section Two</a>
...浏览器窗口将滚动...到最小可能位置以使该元素完全可见。...与浏览器窗口的上边缘齐平。这可能是……在固定位置、保持在顶部的标头的情况下,问题很大。
事实上,我们的固定顶部导航看起来很像 buddycloud 的(我们的是 82 像素高)。我们的页内哈希链接隐藏在它下面,就像他们的一样。
除了两个重要的例外:首先,如果目标“散列” URL 与出站链接位于同一个降价文件中,则目标从固定标题下干净地窥视,就像左导航链接一样。(在源端,Slate 将所有内容存储为.md
文件。)这将问题本地化:链接目标仅隐藏在 Slate 必须遍历到单独的目标.md
文件,然后连接#<SomeAnchorName>
以完成 URL 的位置。
其次,我们发现了一个 hack,它可以获取所有“页内”散列链接以清除我们的顶部标题。这涉及使用两个跨度在 HTML 中对我们的标题进行双重标记。第一个是一个空的虚拟跨度,它位于实际标题文本上方以欺骗滚动行为。(它用我们上面的jumptarget
类进行了标记。)在标题本身上,我们应用了一个带有类的单独跨度,它纠正了第一次 hack 中的左缩进。双重标记如下所示:
<h2>
<span class="jumptarget" id="bogusN"> </span>
<span class="jumpleft"> Bogus Heading 2 </span>
</h2>
但是,尽管这揭示了我们的“页内”散列链接,但它完全破坏了我们的左侧导航。由于与 Slate 的tocify
左导航生成器的一些交互,以这种方式标记的任何标题都会出现以下行为: (1) 将其子项隐藏在左导航中。(2) 单击时,防止jumptarget
类从顶部标题下方滚动出来。(3) 单击时,在左侧导航中折叠其父级。
所以总而言之,我们的困境是:我们对左侧导航链接的修复导致我们的文本链接断开。然而,我们对文本链接的修复破坏了我们的左导航修复。
如果有人在 Tripit Slate 或tocify
或其他框架上全局解决了这个问题,我们将非常感谢您的指点。干净的 CSS、hacky HTML 或 jivey JavaScript——我们是不可知论者。谢谢!
[2016 年 7 月 13 日更新:] 这是我们的开发人员添加到的脚本layout.erb
,用于清除链接目标被持久标头隐藏。我们正在测试它是否适用于所有链接。非常邀请评论:
<script>
var container = $('.page-wrapper .content');
var body = $('body');
var headerHeightPixels = 85;
container.on('click', function(event) {
var target = $(event.target);
if (target.is('a') && target.attr('href').charAt(0) === '#') {
setTimeout(function() {
$('body').scrollTop($('body').scrollTop() - headerHeightPixels)
}, 0);
}
});
</script>