在 typecho 上实现锚点功能

在 typecho 上实现锚点功能

xiaolu
2022-02-17 / 1 评论 / 32 阅读 / 正在检测是否收录...
温馨提示:
本文最后更新于2022年02月17日,已超过172天没有更新,若内容或图片失效,请留言反馈。

最近在写一些前端的读书笔记,有的时候整个页面太长,想要快速定位到一些特定的位置只能依靠鼠标滚轮,而且使用的主题没有目录,所以动动手实现一下锚点功能。

大致原理

基本原理是 暗锚 ,我的实际需求是在 markdown 文档里加入锚点功能,就是点击页面内某个链接能够跳转到页面上的某个特定位置。那种 JS 监听链接的点击然后控制页面滚动的方法实在麻烦,实现起来要计算元素高度之类的,因此这种方式不可行。所以还是考虑使用浏览器的原始功能,给被锚元素添加 id,然后使用 a 标签链接到这个元素上。

暗锚 的意思就是找另外一个元素 B 替代原始元素 A,原本是点击链接 C 时跳转到 A,现在点击链接 C 时跳转到 B,而 A B 两个元素是挨着的,跳转的位置就是那一片区域,所以在用户体验上是无感知的。

实现起来很简单,就是需要注意一些细节:

  • markdown 的链接默认是新标签页打开
  • 隐藏锚点元素不能使用 display:none;

JS 部分

一定要等待全文加载完毕再执行下面的代码,不然 links 数组是空的。最好就是以单独 JS 文件的形式,引入到 body 的最下方。

<!-- body 底部 --> 
<script src="https://henrenx.cn/anchor.js"></script>

首先就是判断当前是不是文章页,如果是的话就找到文章中所有的 a 标签,然后看它的 href 是不是以 # 开头的页内链接,因为 markdown 的链接默认是新标签页,所以要把它的打开方式设置为页内。

$(function () {
    let url = document.location.href;
    if (!url.includes('archives')) {
        return;
    }
    let links = $(".joe_detail__article a");
    for (let i = 0; i < links.length; i++) {
        let href = $(links[i]).attr('href');
        if (href && href.startsWith('#')) {
            $(links[i]).attr("target", "_self");
        }
    }
    $(".joe_detail__article a[type='anchor']").parent().addClass('self_anchor');
});

CSS 部分

然后把这段 css 样式加入到全局中,目的就是把目标元素隐藏起来。为什么不用 display: none;这种方式呢?因为加了它就不能实现锚点功能了,点击链接是跳转不到指定位置的,具体原因不知,但是不能用。

.self_anchor {
  margin: 0; 
  font-size: 0; 
  height: 0; 
  top: -100px;
  position: relative;
}

需要注意的是,top 的值要适当调整,因为好多这种博客主题都是带顶栏的,点击链接实际上是锚到了相应元素,但是被顶栏遮住了,因此要将 A、B 元素适当分开些,分开的距离抵消了顶栏的高度,这时的功能才算正常。

用法

// 暗锚
<a type="anchor" id="anchorId"></a>
\## This is subtitle

// 链接
[点击跳转](#anchorId)

大致原理

JS 部分

CSS 部分

用法

0

评论 (1)

取消
  1. 头像
    xiaolu 作者
    Windows 10 · Google Chrome

    因为我的这个主题上下滚动时,顶栏不一样,所以更加合理的解决方案是:

    划分上锚和下锚滑动两个样式
    然后把对应的 css 改成俩方案,同时 JS 里边也改改

    我有空再改叭。。。

    回复