Skip to content

Commit 1c57ced

Browse files
committed
refactor: lock-scroll prop
1 parent 78e60f9 commit 1c57ced

File tree

12 files changed

+104
-64
lines changed

12 files changed

+104
-64
lines changed

dist/VueFinalModal.esm.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/VueFinalModal.esm.js.map

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/VueFinalModal.umd.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/VueFinalModal.umd.js.map

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

example/src/components/basic/BasicOptions.vue

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,11 @@
33
<v-modal
44
v-model="showModal"
55
:ssr="ssr"
6-
:lockScroll="lockScroll"
7-
:hideOverlay="hideOverlay"
8-
:clickToClose="clickToClose"
9-
:escToClose="escToClose"
10-
:preventClick="preventClick"
6+
:lock-scroll="lockScroll"
7+
:hide-overlay="hideOverlay"
8+
:click-to-close="clickToClose"
9+
:esc-to-close="escToClose"
10+
:prevent-click="preventClick"
1111
:transition="transition ? 'vfm' : ''"
1212
:overlay-transition="overlayTransition ? 'vfm' : ''"
1313
:z-index-auto="zIndexAuto"

lib/Plugin.js

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,9 @@
11
import { bindPrototype, registComponent } from './PluginCore'
22
import { DUPLICATE_PLUGIN_COMPONENT, DUPLICATE_COMPONENT } from './utils/errors'
3-
import mobile from 'is-mobile'
43

54
const defaultOptions = {
65
componentName: 'VueFinalModal',
7-
key: '$vfm',
8-
isMobile: mobile()
6+
key: '$vfm'
97
}
108

119
const Plugin = () => ({

lib/PluginCore.js

Lines changed: 2 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import VueFinalModal from './VueFinalModal.vue'
2-
import { setStyle, removeStyle } from './utils/dom.js'
32

4-
function createVfm(options) {
3+
function createVfm() {
54
let vfm
65

76
return function() {
@@ -23,27 +22,6 @@ function createVfm(options) {
2322
modal.toggle(...args)
2423
}
2524
},
26-
isScrollLocked: false,
27-
lockScroll() {
28-
if (this.isScrollLocked) return
29-
if (options.isMobile) {
30-
setStyle(document.body, 'overflow', 'hidden')
31-
} else {
32-
window.addEventListener('wheel', this.lockScrollListener, { passive: false })
33-
}
34-
this.isScrollLocked = true
35-
},
36-
unlockScroll() {
37-
if (options.isMobile) {
38-
removeStyle(document.body, 'overflow')
39-
} else {
40-
window.removeEventListener('wheel', this.lockScrollListener)
41-
}
42-
this.isScrollLocked = false
43-
},
44-
lockScrollListener(e) {
45-
e.preventDefault()
46-
},
4725
get(name) {
4826
return this.modals.find(modal => modal.name === name)
4927
},
@@ -57,7 +35,7 @@ function createVfm(options) {
5735
}
5836

5937
export function bindPrototype(Vue, options) {
60-
const vfm = createVfm(options)()
38+
const vfm = createVfm()()
6139
Object.defineProperty(Vue.prototype, options.key, {
6240
get() {
6341
return vfm

lib/VueFinalModal.vue

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@
5555

5656
<script>
5757
import FocusTrap from './utils/focusTrap.js'
58+
import { disableBodyScroll, enableBodyScroll } from './utils/bodyScrollLock'
5859
5960
const TransitionState = {
6061
Enter: 'enter',
@@ -236,7 +237,13 @@ export default {
236237
},
237238
handleLockScroll() {
238239
if (this.value) {
239-
this.lockScroll ? this.api.lockScroll() : this.api.unlockScroll()
240+
if (this.lockScroll) {
241+
disableBodyScroll(this.$refs.vfmContent, {
242+
reserveScrollBarGap: true
243+
})
244+
} else {
245+
enableBodyScroll(this.$refs.vfmContent)
246+
}
240247
}
241248
},
242249
getAttachElement() {
@@ -293,7 +300,7 @@ export default {
293300
this.modalStackIndex = null
294301
295302
if (this.api.openedModals.length === 0) {
296-
this.lockScroll && this.api.unlockScroll()
303+
this.lockScroll && enableBodyScroll(this.$refs.vfmContent)
297304
}
298305
299306
let stopEvent = false

lib/utils/bodyScrollLock.js

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
// stolen from body-scroll-lock and removed ios part
2+
3+
let locks = []
4+
let previousBodyOverflowSetting
5+
let previousBodyPaddingRight
6+
7+
const setOverflowHidden = options => {
8+
// If previousBodyPaddingRight is already set, don't set it again.
9+
if (previousBodyPaddingRight === undefined) {
10+
const reserveScrollBarGap = !!options && options.reserveScrollBarGap === true
11+
const scrollBarGap = window.innerWidth - document.documentElement.clientWidth
12+
13+
if (reserveScrollBarGap && scrollBarGap > 0) {
14+
const computedBodyPaddingRight = parseInt(getComputedStyle(document.body).getPropertyValue('padding-right'), 10)
15+
previousBodyPaddingRight = document.body.style.paddingRight
16+
document.body.style.paddingRight = `${computedBodyPaddingRight + scrollBarGap}px`
17+
}
18+
}
19+
// If previousBodyOverflowSetting is already set, don't set it again.
20+
if (previousBodyOverflowSetting === undefined) {
21+
previousBodyOverflowSetting = document.body.style.overflow
22+
document.body.style.overflow = 'hidden'
23+
}
24+
}
25+
26+
const restoreOverflowSetting = () => {
27+
if (previousBodyPaddingRight !== undefined) {
28+
document.body.style.paddingRight = previousBodyPaddingRight
29+
30+
// Restore previousBodyPaddingRight to undefined so setOverflowHidden knows it
31+
// can be set again.
32+
previousBodyPaddingRight = undefined
33+
}
34+
35+
if (previousBodyOverflowSetting !== undefined) {
36+
document.body.style.overflow = previousBodyOverflowSetting
37+
38+
// Restore previousBodyOverflowSetting to undefined
39+
// so setOverflowHidden knows it can be set again.
40+
previousBodyOverflowSetting = undefined
41+
}
42+
}
43+
44+
export const disableBodyScroll = (targetElement, options) => {
45+
// targetElement must be provided
46+
if (!targetElement) {
47+
// eslint-disable-next-line no-console
48+
console.error(
49+
'disableBodyScroll unsuccessful - targetElement must be provided when calling disableBodyScroll on IOS devices.'
50+
)
51+
return
52+
}
53+
54+
// disableBodyScroll must not have been called on this targetElement before
55+
if (locks.some(lock => lock.targetElement === targetElement)) {
56+
return
57+
}
58+
59+
const lock = {
60+
targetElement,
61+
options: options || {}
62+
}
63+
64+
locks = [...locks, lock]
65+
66+
setOverflowHidden(options)
67+
}
68+
69+
export const enableBodyScroll = targetElement => {
70+
if (!targetElement) {
71+
// eslint-disable-next-line no-console
72+
console.error(
73+
'enableBodyScroll unsuccessful - targetElement must be provided when calling enableBodyScroll on IOS devices.'
74+
)
75+
return
76+
}
77+
78+
locks = locks.filter(lock => lock.targetElement !== targetElement)
79+
80+
if (!locks.length) {
81+
restoreOverflowSetting()
82+
}
83+
}

lib/utils/dom.js

Lines changed: 0 additions & 18 deletions
This file was deleted.

0 commit comments

Comments
 (0)