内容目录
痛点
在文章内容中包含脚注 1 后,对脚注感兴趣的读者会点击脚注以跳转到文末阅读注释,当脚注阅读完成后,再点击回到原位置继续阅读。此时,若脚注链接颜色不是很明显,读者会失去阅读焦点,从而给继续阅读造成障碍。
解决方案
本文提供解决方案是:当检测到读者是从脚注跳回时,给读者一个原脚注引用位置的提示。
具体实现思路为:检测到用户点击脚注返回原引用位置的过程中,当脚注锚链重新出现在浏览器的视口(Viewport)中后,闪烁此脚注引起注意。
实现方式
在 src\styles\base.css 末尾增加一个动画类 blinking
.blinking {
animation: blink .5s ease-in-out infinite;
}
@keyframes blink {
0% {
opacity: 1;
background: black;
}
25% {
opacity: 0;
background: white;
}
50% {
opacity: 1;
background: black;
}
75% {
opacity: 0;
background: white;
}
100% {
opacity: 1;
background: black;
}
}
在 src\layouts\Layout.astro 中增加处理事件,这里值得注意的是,由于 Astro Paper 主题异步加载文章,对于文章中脚注点击事件需要实现预绑定,即 DOM 元素未加载时先绑定点击事件,实现方式为在上级节点绑定点击事件,在点击后过滤节点。
<script is:inline>
let timerAnchor;
document.addEventListener("DOMContentLoaded", () => {
document.addEventListener('click', function(e) {
const links = document.getElementById('article').getElementsByTagName('a');
for (let i = 0; i < links.length; i++) {
const match = links[i].hash.match(/#(.*)-fnref-\d+$/);
if (match) {
links[i].onclick = function (event) {
const target = event.srcElement || event.target;
timerAnchor = setInterval(checkAnchorInViewport, 100, target.hash);
};
}
}
});
function checkAnchorInViewport(hash) {
const el = document.getElementById(hash.slice(1, hash.length));
if (isElInViewport(el)) {
clearInterval(timerAnchor);
el.classList.add('blinking');
setTimeout(() => { el.classList.remove('blinking'); }, 1000);
}
}
function isElInViewport(element) {
const rect = element.getBoundingClientRect();
return (
rect.top >= 0 &&
rect.left >= 0 &&
rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) &&
rect.right <= (window.innerWidth || document.documentElement.clientWidth)
);
}
});
</script>
脚注
Footnotes
-
脚注:这个脚注的存在是为了方便体验本文实现的“脚注闪烁”效果,可以尝试点击最后的返回箭头。 ↩