Skip to content

Instantly share code, notes, and snippets.

@zaydek-old
Created October 8, 2019 05:34
Show Gist options
  • Save zaydek-old/848e920f31f1935da57094090557a739 to your computer and use it in GitHub Desktop.
Save zaydek-old/848e920f31f1935da57094090557a739 to your computer and use it in GitHub Desktop.
// Branch A:
//
// :::::::::::::: <- window.scrollY
// +------------+
// |+----------+| <- topBuffer
// || node || <- y
// |+----------+|
// || |
// +------------+
//
// Branch B:
//
// :::::::::::::: <- window.scrollY
// +------------+ <---------------+
// | | |
// |+----------+| <- y |
// || node || <- height | <- window.innerHeight
// |+----------+| <- bottomBuffer |
// +------------+ <---------------+
//
function newY(topBuffer, bottomBuffer) {
const selection = document.getSelection()
if (!selection.anchorNode) {
// No bounds.
return -1
}
const rects = selection.getRangeAt(0).getClientRects()
if (!rects.length) {
// No bounds.
return -1
}
const [y1, y2] = [window.scrollY + rects[0].y, window.scrollY + rects[0].y + rects[0].height]
const [top, bottom] = [window.scrollY + topBuffer, window.scrollY + window.innerHeight - bottomBuffer]
if (y1 < top) {
return y1 - topBuffer
} else if (y2 > bottom) {
return y2 - window.innerHeight + bottomBuffer
}
// In bounds.
return -1
}
// E.g.:
//
// const scrollIntoViewIfNeeded = genScrollIntoViewIfNeeded(SCROLL_BUFFER)
//
// ...
//
// scrollIntoViewIfNeeded()
//
const genScrollIntoViewIfNeeded = (topBuffer = 0, bottomBuffer = topBuffer) => () => {
const y = newY(topBuffer, bottomBuffer)
if (y === -1) {
return
}
window.scrollTo(0, y)
}
export default genScrollIntoViewIfNeeded
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment