From 8b321f6f1fd8b906cd9e224bbfc2356c8e4e4235 Mon Sep 17 00:00:00 2001 From: taehoon Date: Fri, 19 Jul 2019 12:27:03 -0400 Subject: add body-scroll-lock directive --- src/directives/body_scroll_lock.js | 69 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 69 insertions(+) create mode 100644 src/directives/body_scroll_lock.js (limited to 'src/directives/body_scroll_lock.js') diff --git a/src/directives/body_scroll_lock.js b/src/directives/body_scroll_lock.js new file mode 100644 index 00000000..6ab20c3f --- /dev/null +++ b/src/directives/body_scroll_lock.js @@ -0,0 +1,69 @@ +import * as bodyScrollLock from 'body-scroll-lock' + +let previousNavPaddingRight +let previousAppBgWrapperRight + +const disableBodyScroll = (el) => { + const scrollBarGap = window.innerWidth - document.documentElement.clientWidth + bodyScrollLock.disableBodyScroll(el, { + reserveScrollBarGap: true + }) + setTimeout(() => { + // If previousNavPaddingRight is already set, don't set it again. + if (previousNavPaddingRight === undefined) { + const navEl = document.getElementById('nav') + previousNavPaddingRight = window.getComputedStyle(navEl).getPropertyValue('padding-right') + navEl.style.paddingRight = previousNavPaddingRight ? `calc(${previousNavPaddingRight} + ${scrollBarGap}px)` : `${scrollBarGap}px` + } + // If previousAppBgWrapeprRight is already set, don't set it again. + if (previousAppBgWrapperRight === undefined) { + const appBgWrapperEl = document.getElementById('app_bg_wrapper') + previousAppBgWrapperRight = window.getComputedStyle(appBgWrapperEl).getPropertyValue('right') + appBgWrapperEl.style.right = previousAppBgWrapperRight ? `calc(${previousAppBgWrapperRight} + ${scrollBarGap}px)` : `${scrollBarGap}px` + } + document.body.classList.add('scroll-locked') + }) +} + +const enableBodyScroll = (el) => { + setTimeout(() => { + if (previousNavPaddingRight !== undefined) { + document.getElementById('nav').style.paddingRight = previousNavPaddingRight + // Restore previousNavPaddingRight to undefined so disableBodyScroll knows it can be set again. + previousNavPaddingRight = undefined + } + if (previousAppBgWrapperRight !== undefined) { + document.getElementById('app_bg_wrapper').style.right = previousAppBgWrapperRight + // Restore previousAppBgWrapperRight to undefined so disableBodyScroll knows it can be set again. + previousAppBgWrapperRight = undefined + } + document.body.classList.remove('scroll-locked') + }) + bodyScrollLock.enableBodyScroll(el) +} + +const directive = { + inserted: (el, binding) => { + if (binding.value) { + disableBodyScroll(el) + } + }, + componentUpdated: (el, binding) => { + if (binding.oldValue === binding.value) { + return + } + + if (binding.value) { + disableBodyScroll(el) + } else { + enableBodyScroll(el) + } + }, + unbind: (el) => { + enableBodyScroll(el) + } +} + +export default (Vue) => { + Vue.directive('body-scroll-lock', directive) +} -- cgit v1.2.3-70-g09d2 From 093d785fbf8c982421f0098ad4b48c9d96b85ee8 Mon Sep 17 00:00:00 2001 From: taehoon Date: Thu, 17 Oct 2019 16:03:41 -0400 Subject: handle multiple body scroll lockers --- src/directives/body_scroll_lock.js | 55 +++++++++++++++++++++++--------------- 1 file changed, 33 insertions(+), 22 deletions(-) (limited to 'src/directives/body_scroll_lock.js') diff --git a/src/directives/body_scroll_lock.js b/src/directives/body_scroll_lock.js index 6ab20c3f..a375e852 100644 --- a/src/directives/body_scroll_lock.js +++ b/src/directives/body_scroll_lock.js @@ -2,42 +2,53 @@ import * as bodyScrollLock from 'body-scroll-lock' let previousNavPaddingRight let previousAppBgWrapperRight +let lockerEls = [] const disableBodyScroll = (el) => { const scrollBarGap = window.innerWidth - document.documentElement.clientWidth bodyScrollLock.disableBodyScroll(el, { reserveScrollBarGap: true }) + if (!lockerEls.includes(el)) { + lockerEls.push(el) + } setTimeout(() => { - // If previousNavPaddingRight is already set, don't set it again. - if (previousNavPaddingRight === undefined) { - const navEl = document.getElementById('nav') - previousNavPaddingRight = window.getComputedStyle(navEl).getPropertyValue('padding-right') - navEl.style.paddingRight = previousNavPaddingRight ? `calc(${previousNavPaddingRight} + ${scrollBarGap}px)` : `${scrollBarGap}px` - } - // If previousAppBgWrapeprRight is already set, don't set it again. - if (previousAppBgWrapperRight === undefined) { - const appBgWrapperEl = document.getElementById('app_bg_wrapper') - previousAppBgWrapperRight = window.getComputedStyle(appBgWrapperEl).getPropertyValue('right') - appBgWrapperEl.style.right = previousAppBgWrapperRight ? `calc(${previousAppBgWrapperRight} + ${scrollBarGap}px)` : `${scrollBarGap}px` + if (lockerEls.length <= 1) { + // If previousNavPaddingRight is already set, don't set it again. + if (previousNavPaddingRight === undefined) { + const navEl = document.getElementById('nav') + previousNavPaddingRight = window.getComputedStyle(navEl).getPropertyValue('padding-right') + navEl.style.paddingRight = previousNavPaddingRight ? `calc(${previousNavPaddingRight} + ${scrollBarGap}px)` : `${scrollBarGap}px` + } + // If previousAppBgWrapeprRight is already set, don't set it again. + if (previousAppBgWrapperRight === undefined) { + const appBgWrapperEl = document.getElementById('app_bg_wrapper') + previousAppBgWrapperRight = window.getComputedStyle(appBgWrapperEl).getPropertyValue('right') + appBgWrapperEl.style.right = previousAppBgWrapperRight ? `calc(${previousAppBgWrapperRight} + ${scrollBarGap}px)` : `${scrollBarGap}px` + } + document.body.classList.add('scroll-locked') } - document.body.classList.add('scroll-locked') }) } const enableBodyScroll = (el) => { + if (lockerEls.includes(el)) { + lockerEls = lockerEls.filter(e => e !== el) + } setTimeout(() => { - if (previousNavPaddingRight !== undefined) { - document.getElementById('nav').style.paddingRight = previousNavPaddingRight - // Restore previousNavPaddingRight to undefined so disableBodyScroll knows it can be set again. - previousNavPaddingRight = undefined - } - if (previousAppBgWrapperRight !== undefined) { - document.getElementById('app_bg_wrapper').style.right = previousAppBgWrapperRight - // Restore previousAppBgWrapperRight to undefined so disableBodyScroll knows it can be set again. - previousAppBgWrapperRight = undefined + if (!lockerEls.length) { + if (previousNavPaddingRight !== undefined) { + document.getElementById('nav').style.paddingRight = previousNavPaddingRight + // Restore previousNavPaddingRight to undefined so disableBodyScroll knows it can be set again. + previousNavPaddingRight = undefined + } + if (previousAppBgWrapperRight !== undefined) { + document.getElementById('app_bg_wrapper').style.right = previousAppBgWrapperRight + // Restore previousAppBgWrapperRight to undefined so disableBodyScroll knows it can be set again. + previousAppBgWrapperRight = undefined + } + document.body.classList.remove('scroll-locked') } - document.body.classList.remove('scroll-locked') }) bodyScrollLock.enableBodyScroll(el) } -- cgit v1.2.3-70-g09d2 From c23a87d8ff7dfed662b5288d6fb77da1a7b3ebbc Mon Sep 17 00:00:00 2001 From: taehoon Date: Mon, 21 Oct 2019 15:56:16 -0400 Subject: update condition --- src/directives/body_scroll_lock.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/directives/body_scroll_lock.js') diff --git a/src/directives/body_scroll_lock.js b/src/directives/body_scroll_lock.js index a375e852..d7f114b5 100644 --- a/src/directives/body_scroll_lock.js +++ b/src/directives/body_scroll_lock.js @@ -36,7 +36,7 @@ const enableBodyScroll = (el) => { lockerEls = lockerEls.filter(e => e !== el) } setTimeout(() => { - if (!lockerEls.length) { + if (lockerEls.length === 0) { if (previousNavPaddingRight !== undefined) { document.getElementById('nav').style.paddingRight = previousNavPaddingRight // Restore previousNavPaddingRight to undefined so disableBodyScroll knows it can be set again. -- cgit v1.2.3-70-g09d2 From eb695fd61d97a8b4ce9de9c65b0133515d087a2c Mon Sep 17 00:00:00 2001 From: taehoon Date: Mon, 21 Oct 2019 20:57:36 -0400 Subject: refactor using Set --- src/directives/body_scroll_lock.js | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) (limited to 'src/directives/body_scroll_lock.js') diff --git a/src/directives/body_scroll_lock.js b/src/directives/body_scroll_lock.js index d7f114b5..13a6de1c 100644 --- a/src/directives/body_scroll_lock.js +++ b/src/directives/body_scroll_lock.js @@ -2,18 +2,16 @@ import * as bodyScrollLock from 'body-scroll-lock' let previousNavPaddingRight let previousAppBgWrapperRight -let lockerEls = [] +const lockerEls = new Set([]) const disableBodyScroll = (el) => { const scrollBarGap = window.innerWidth - document.documentElement.clientWidth bodyScrollLock.disableBodyScroll(el, { reserveScrollBarGap: true }) - if (!lockerEls.includes(el)) { - lockerEls.push(el) - } + lockerEls.add(el) setTimeout(() => { - if (lockerEls.length <= 1) { + if (lockerEls.size <= 1) { // If previousNavPaddingRight is already set, don't set it again. if (previousNavPaddingRight === undefined) { const navEl = document.getElementById('nav') @@ -32,11 +30,9 @@ const disableBodyScroll = (el) => { } const enableBodyScroll = (el) => { - if (lockerEls.includes(el)) { - lockerEls = lockerEls.filter(e => e !== el) - } + lockerEls.delete(el) setTimeout(() => { - if (lockerEls.length === 0) { + if (lockerEls.size === 0) { if (previousNavPaddingRight !== undefined) { document.getElementById('nav').style.paddingRight = previousNavPaddingRight // Restore previousNavPaddingRight to undefined so disableBodyScroll knows it can be set again. -- cgit v1.2.3-70-g09d2