Skip to content

Commit

Permalink
fix: better locking of body scroll
Browse files Browse the repository at this point in the history
  • Loading branch information
goblindegook committed Feb 3, 2020
1 parent cbb9b9b commit d9b609c
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 13 deletions.
43 changes: 35 additions & 8 deletions src/dom/events.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { throttle } from '@pacote/throttle'
import { getStyle } from '@pacote/get-style'
import { off, on } from 'delegated-events'
import { CoreDriver, FootnoteAction, FootnoteLookup } from '../core'

Expand All @@ -9,7 +10,6 @@ const SELECTOR_BUTTON = '[data-footnote-button]'
const SELECTOR_FOOTNOTE = '[data-footnote-id]'
const SELECTOR_POPOVER = '[data-footnote-popover]'
const CLASS_FULLY_SCROLLED = 'is-fully-scrolled'
const CLASS_NO_SCROLL = 'littlefoot-no-scroll'

function target(event: Event) {
return event.target as HTMLElement
Expand All @@ -19,6 +19,32 @@ function getFootnoteId(element: HTMLElement | null): string | undefined {
return element?.dataset.footnoteId
}

let initialBodyStyleOverflow: string | undefined
let initialBodyPadding: string | undefined

function lockBodyScroll(): void {
if (initialBodyStyleOverflow === undefined) {
initialBodyPadding = getStyle(document.body, 'paddingRight')
initialBodyStyleOverflow = getStyle(document.body, 'overflow')
const scrollBarWidth =
window.innerWidth - document.documentElement.clientWidth
document.body.style.overflow = 'hidden'
document.body.style.paddingRight = scrollBarWidth + 'px'
}
}

function unlockBodyScroll(): void {
if (initialBodyStyleOverflow) {
document.body.style.overflow = initialBodyStyleOverflow
initialBodyStyleOverflow = undefined
}

if (initialBodyPadding) {
document.body.style.paddingRight = initialBodyPadding
initialBodyPadding = undefined
}
}

function handleTouch(
lookup: FootnoteLookup,
action: FootnoteAction,
Expand Down Expand Up @@ -54,7 +80,12 @@ function handleHover(
}

function handleEscape(fn: () => void): EventHandler<KeyboardEvent> {
return event => event.keyCode === 27 && fn()
return event => {
if (event.keyCode === 27) {
unlockBodyScroll()
fn()
}
}
}

function handleScroll(popover: HTMLElement): EventHandler<WheelEvent> {
Expand All @@ -81,12 +112,8 @@ export function bindScrollHandler(
popover: HTMLElement
): void {
content.addEventListener('wheel', throttle(handleScroll(popover), FRAME))
content.addEventListener('mouseover', () => {
document.body.classList.add(CLASS_NO_SCROLL)
})
content.addEventListener('mouseout', () => {
document.body.classList.remove(CLASS_NO_SCROLL)
})
content.addEventListener('mouseover', lockBodyScroll)
content.addEventListener('mouseout', unlockBodyScroll)
}

export function addListeners({
Expand Down
2 changes: 1 addition & 1 deletion src/dom/footnote.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ export function createFootnote({

button.insertAdjacentElement('afterend', popover)

popover.style.maxWidth = `${document.body.clientWidth}px`
popover.style.maxWidth = document.body.clientWidth + 'px'
const contentMaxHeight = getStyle(content, 'maxHeight')
maxHeight = Math.round(pixels(contentMaxHeight, content))

Expand Down
4 changes: 0 additions & 4 deletions styles/_littlefoot-content.scss
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,6 @@
// @state .is-positioned-top - The popover is above the button.
// @state .is-positioned-bottom - The popover is below the button.

.littlefoot-no-scroll {
overflow: hidden;
}

.littlefoot-footnote {
background: $popover-color-background;
border-radius: $popover-border-radius;
Expand Down

0 comments on commit d9b609c

Please sign in to comment.