前言
很多博客中最常见的问题就是:文章很长,但是读者很忙。下次阅读的时候,可能要花一些时间才能恢复到先前的阅读位置。
如果可以设备间,识别二维码或是一个链接就可以让阅读无缝衔接,直接跳转到相应位置,那么阅读体验就会变得更加优秀。
那么,开始吧!
实践
要知道阅读位置,那么就要知道当前页面的坐标。
const getScrollPosition = (el = window) => ({ x: el.pageXOffset !== undefined ? el.pageXOffset : el.scrollLeft, y: el.pageYOffset !== undefined ? el.pageYOffset : el.scrollTop });
|
大部分情况下,我们只用关注纵坐标。横坐标大概率为 0
。
我们还需要一个页面滚动的事件,用于记录当前坐标,并储存在临时存储中。
至于为什么是 sessionStorage
而不是 localStorage
,则是因为 localStorage
除手动清除外,不会自动过期。
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.setItem("read_y", p); } window.onscroll = windowScroll;
|
你可能发现了,此处的变量 p
,并不仅仅是「页面纵坐标」,而是「页面高度」与「纵坐标」的组合字符串。
事实上,如果单纯是纵坐标判断位置,那么在不同高度,不同宽度的设备上,就会出现错位的情况。而同时记录三个信息,就可以还原真实坐标。
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 { 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 主题将在下个版本中更新该功能。