Skip to content

Instantly share code, notes, and snippets.

@barneycarroll
Last active December 12, 2017 12:15
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save barneycarroll/365870576c4748bd1d60e481c0a23c2b to your computer and use it in GitHub Desktop.
Save barneycarroll/365870576c4748bd1d60e481c0a23c2b to your computer and use it in GitHub Desktop.
War on scrolling! Paginate web pages and use arrow keys or a small UI to navigate between screens
const $spans = [...document.querySelectorAll('*')]
.map($ =>
[...$.childNodes].filter($ =>
$.nodeType === 3
)
)
.reduce((a, b) =>
[...a, ...b]
)
.map(textNode => {
const $span = document.createElement('span')
$span.appendChild(textNode.cloneNode())
textNode.replaceWith($span)
return $span
})
const [[margin]] = $spans
.map($ =>
$.getBoundingClientRect().left
)
.sort((a, b) =>
a > b ? 1 : -1
)
.reduce(
([last, ...previous], current) =>
[
...(
current === last[0]
?
[[current, ...last]]
:
[[current], last]
),
...previous
],
[[]]
)
.sort((a, b) =>
a.length < b.length ? 1 : -1
)
$spans.forEach($ =>
$.replaceWith($.firstChild)
)
const pages = [...document.querySelectorAll('*')]
.filter($ =>
getComputedStyle($).display === 'block'
&&
$.offsetHeight < innerHeight
)
.reduce(
($$, $, i) => (
i && $$[$$.length - 1].contains($)
?
$$
:
[...$$, $]
),
[]
)
.map($ => ({
$,
top: $.offsetTop,
bottom: $.offsetTop + $.offsetHeight,
}))
.reduce(
({pages, offset}, {$, top, bottom}) => {
const edge = pages * innerHeight,
over = edge <= bottom + offset,
inter = edge - margin <= offset + bottom
&&
edge + margin >= offset + top
if(over || inter)
pages++
if(inter){
const $gap = document.createElement('div')
const gap = edge - top + margin
$gap.style.height = gap + 'px'
$.prepend($gap)
offset += gap
}
return {
pages,
offset,
}
},
{
pages: 1,
offset: 0,
}
)
.pages - 1
document.head.appendChild(
Object.assign(
document.createElement('script'),
{
src: 'https://unpkg.com/mithril',
onload: () => {
let page = 0
Object.assign(document.body.style, {
overflow: 'hidden',
height: innerHeight * pages + 'px',
})
const back = () =>
m.redraw(page && page--)
const forð = () =>
m.redraw(page < pages && page++)
document.addEventListener('keydown', ({key}) =>
key === 'ArrowLeft' && back()
||
key === 'ArrowRight' && forð()
)
m.mount(
document.body.appendChild(
document.createElement('div')
),
{
view : () => (
scrollTo(0, page * innerHeight),
m('div', {
style : {
background: 'hsla(0,0,100,80)',
position: 'fixed',
bottom: 0,
right: 0,
zIndex: 9999,
},
},
m('button', {onclick : back}, '<'),
' ',
m('span', page, '/', pages),
' ',
m('button', {onclick : forð}, '>')
)
)
}
)
}
}
)
)
@barneycarroll
Copy link
Author

Revision 3

Fixed the blind-coding errors but now the gaps mechanism is broken 🤔

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment