我有一本书的很大一章可供用户阅读。章节可以具有任何字体大小。窗口可以是任何大小。如何在数据库中文本的正确位置(当前可见窗口的顶部)保存确切的位置,所以当用户继续从任何设备阅读本章时,我可以将其滚动到那里?
我尝试使用window.pageYOffset
,然后尝试滚动位置的百分比,但是它对于动态窗口和字体大小并不准确,并且只能在相同的环境(字体大小,窗口大小)中工作。
我现在唯一的想法是将本章分成几行:
const lines = (chapter.match(/\r?\n/g) || '').length + 1
然后以某种方式找到当前可见窗口最上方的一行,保存其编号,并在加载时滚动到该行。
作为替代方案,也许可以提供一些当前最可见的html元素,以便我坚持下去。
有什么想法吗?
更新:现在,我正在尝试获取内容div
的父级中的所有元素,并通过它们进行迭代以使用getBoundingClientRect()
获取元素在视口中的位置。我对此有希望。
答案 0 :(得分:0)
首先,您获得了一组段落
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
}
}
现在,您可以将此closetIndex保存在数据库中,并在下次加载时滚动至该索引:
let children = Array.from(contentRef.current.children)
window.scrollTo(0, children[localStorage.getItem('index')].offsetTop)