让阅读无缝衔接 —— JS 获取用户阅读进度
CKY 于 2022/11/12 在「博客」发布。
标签: #Miracle#博客#JavaScript
很多博客中最常见的问题就是:文章很长,但是读者很忙。下次阅读的时候,可能要花一些时间才能恢复到先前的阅读位置。如果可以设备间,识别二维码或是一个链接就可以让阅读无缝衔接,直接跳转到相应位置,那么阅读体验就会变得更加优秀。那么,开始吧!
前言
很多博客中最常见的问题就是:文章很长,但是读者很忙。下次阅读的时候,可能要花一些时间才能恢复到先前的阅读位置。
如果可以设备间,识别二维码或是一个链接就可以让阅读无缝衔接,直接跳转到相应位置,那么阅读体验就会变得更加优秀。
那么,开始吧!
实践
要知道阅读位置,那么就要知道当前页面的坐标。
const getScrollPosition = (el = window) => ({
x: el.pageXOffset !== undefined ? el.pageXOffset : el.scrollLeft,
y: el.pageYOffset !== undefined ? el.pageYOffset : el.scrollTop
});
// getScollPosition().x => 页面横坐标; getScrollPosition().y => 页面纵坐标;
大部分情况下,我们只用关注纵坐标。横坐标大概率为 0
。
我们还需要一个页面滚动的事件,用于记录当前坐标,并储存在临时存储中。
至于为什么是 sessionStorage
而不是 localStorage
,则是因为 localStorage
除手动清除外,不会自动过期。
// 此处的 750 是「页面元素的最大宽度」
var wx = window.innerWidth >= 750 ? 750 : window.innerWidth;
var wy = window.innerHeight;
function windowScroll() {
// 反复修改 确保页面尺寸不改变
wx = window.innerWidth >= 750 ? 750 : window.innerWidth;
wy = window.innerHeight;
let y = Math.round(getScrollPosition().y);
// 组合字符串,同时记录页面坐标,页面宽度和高度
let p = `${y}:${wx}:${wy}`;
// 写入到 sessionStorage 中
sessionStorage.setItem("read_y", p);
}
window.onscroll = windowScroll;
你可能发现了,此处的变量 p
,并不仅仅是「页面纵坐标」,而是「页面高度」与「纵坐标」的组合字符串。
事实上,如果单纯是纵坐标判断位置,那么在不同高度,不同宽度的设备上,就会出现错位的情况。而同时记录三个信息,就可以还原真实坐标。
// URL 中是否包含传递的坐标信息
if (location.hash.split("#read=").length > 1) {
// 分离字符串
let read_y = location.hash.split("#read=")[1];
read_y = read_y.split(":");
// 组合乘积,顺滑移动至坐标
window.scrollTo({top: Math.round(Number(read_y[0]) * Number(read_y[1] * Number(read_y[2] / wx / wy))), behavior: "smooth"});
} else {
// 从 sessionStorage 中获取
let read_y = sessionStorage.getItem("read_y") || "0:0:0";
read_y = read_y.split(":");
window.scrollTo({top: Math.round(Number(read_y[0]) * Number(read_y[1] * Number(read_y[2] / wx / wy))), behavior: "smooth"});
}
到现在,我们已经完成了 URL 的解析和基本生成。
那么,URL 即为:
`${location.protocol}//${location.hostname}${location.port ? ":"+location.port:location.port}${location.pathname}#read=${sessionStorage.getItem("read_y")}`;
最后
搭配生成二维码等插件效果更佳。
Miracle 主题将在下个版本中更新该功能。
由 Google 提供的广告
此广告内容由 Google Ads 提供,与 CKY.IM 无关,请注意识别。为什么会显示广告?