作者热门文章
- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我有一本书的很大一章供我的用户阅读。章节可以有任何字体大小;窗口可以是任何大小。如何在数据库中保存文本中的确切位置(当前可见窗口的最顶部),以便当用户继续从任何设备阅读本章时,我可以将他滚动到那里?
我尝试使用 window.pageYOffset
,然后是滚动位置的百分比,但动态窗口和字体大小不准确,并且只能在相同的环境中工作(字体大小,窗口大小).
我现在唯一的想法是将章节分成几行:
const lines = (chapter.match(/\r?\n/g) || '').length + 1
然后以某种方式找到当前可见窗口最顶部的一行,保存它的编号,并在加载时滚动到它。
作为替代方案,也许可以为我提供当前最可见的 html 元素,以便我坚持使用它。
有什么想法吗?
更新:现在我正在尝试获取内容 div
的父级中的所有元素,并使用 getBoundingClientRect()
遍历它们以获取元素在视口(viewport)中的位置>。我对此抱有希望。
最佳答案
首先你得到段落数组
let children = Array.from(contentRef.current.children)
他们对最接近零(可见屏幕顶部)的段落进行二进制搜索。
let closestIndex = binaryClosest(
children,
target => 0 - target.getBoundingClientRect().y
)
localStorage.setItem('index', closestIndex)
function binaryClosest(a, compare) {
let i = binarySearch()
if (i === 0) return 0
if (i === a.length) return i - 1
let d1 = -compare(a[i]),
d2 = compare(a[i - 1])
return d1 < d2 ? i : i - 1
function binarySearch() {
let le = 0,
ri = a.length - 1
while (le <= ri) {
let mid = (le + ri) >> 1,
cmp = compare(a[mid])
if (cmp > 0) {
le = mid + 1
} else if (cmp < 0) {
ri = mid - 1
} else {
return mid
}
}
return le
}
}
现在您可以将这个 closestIndex 保存在数据库中,并在下次加载时滚动到它:
let children = Array.from(contentRef.current.children)
window.scrollTo(0, children[localStorage.getItem('index')].offsetTop)
关于javascript - 下次访问时恢复动态内容中的阅读位置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55542893/
我是一名优秀的程序员,十分优秀!