Permalink
Browse files

fix(modal): Ensure body scrollbar is removed if modal destroyed befor…

…e being closed (#1168)

* fix(modal): Ensure body scrollbar is removed if modal destroyed before being closed

Use case: If a modal is open on a child route and the route is changed, the modal is closed, but body scrollbar and navbar/fixed content adjustments (margins/padding) were not being removed.

Note this PR does not address similar issues when modal is inside a `<keep-alive>` component.

* Add hasAttr to DOM utils

* make sure old padding removed from mdoal as well

* Update dom.js
  • Loading branch information...
tmorehouse committed Oct 7, 2017
1 parent 7ef0ecc commit e0a4444ab04008f78e162b86ee22801b676f71b7
Showing with 32 additions and 10 deletions.
  1. +22 −9 lib/components/modal.vue
  2. +10 −1 lib/utils/dom.js
@@ -84,9 +84,9 @@
import bBtn from './button';
import bBtnClose from './button-close';
import { idMixin, listenOnRootMixin } from '../mixins';
import { isVisible, selectAll, select, getBCR, addClass, removeClass, setAttr, removeAttr, getAttr, eventOn, eventOff } from '../utils/dom';
import { observeDom, warn } from '../utils';
import { BvEvent } from '../classes';
import { isVisible, selectAll, select, getBCR, addClass, removeClass, setAttr, removeAttr, getAttr, hasAttr, eventOn, eventOff } from '../utils/dom';
const Selector = {
FIXED_CONTENT: '.fixed-top, .fixed-bottom, .is-fixed, .sticky-top',
@@ -546,8 +546,10 @@
},
resetAdjustments() {
const modal = this.$refs.modal;
modal.style.paddingLeft = '';
modal.style.paddingRight = '';
if (modal) {
modal.style.paddingLeft = '';
modal.style.paddingRight = '';
}
},
checkScrollbar() {
const rect = getBCR(document.body);
@@ -596,20 +598,26 @@
resetScrollbar() {
// Restore fixed content padding
selectAll(Selector.FIXED_CONTENT).forEach(el => {
el.style.paddingRight = getAttr(el, 'data-padding-right') || '';
removeAttr(el,'data-padding-right');
if (hasAttr(el, 'data-padding-right')) {
el.style.paddingRight = getAttr(el, 'data-padding-right') || '';
removeAttr(el,'data-padding-right');
}
});
// Restore sticky content and navbar-toggler margin
selectAll(`${Selector.STICKY_CONTENT}, ${Selector.NAVBAR_TOGGLER}`).forEach(el => {
el.style.marginRight = getAttr(el, 'data-margin-right') || '';
removeAttr(el, 'data-margin-right');
if (hasAttr(el, 'data-margin-right')) {
el.style.marginRight = getAttr(el, 'data-margin-right') || '';
removeAttr(el, 'data-margin-right');
}
});
// Restore body padding
const body = document.body;
body.style.paddingRight = getAttr(body, 'data-padding-right') || '';
removeAttr(body, 'data-padding-right');
if (hasAttr(body, 'data-padding-right')) {
body.style.paddingRight = getAttr(body, 'data-padding-right') || '';
removeAttr(body, 'data-padding-right');
}
}
},
@@ -631,11 +639,16 @@
}
},
beforeDestroy() {
// Ensure everything is back to normal
if (this._observer) {
this._observer.disconnect();
this._observer = null;
}
this.setResizeEvent(false);
// Re-adjust body/navbar/fixed padding/margins (if needed)
removeClass(document.body, 'modal-open');
this.resetAdjustments();
this.resetScrollbar();
}
};
</script>
@@ -151,7 +151,15 @@ dom.getAttr = function(el, attr) {
return null;
};

// Retur nteh Bounding Client Rec of an element. Retruns null if not an element
// Determine if an attribute exists on an element (returns true or false, or null if element not found)
dom.hasAttr = function(el, attr) {
if (attr && dom.isElement(el)) {
return el.hasAttribute(attr);
}
return null;
};

// Return the Bounding Client Rec of an element. Retruns null if not an element
dom.getBCR = function(el) {
return dom.isElement(el) ? el.getBoundingClientRect() : null;
};
@@ -238,6 +246,7 @@ export const matches = dom.matches;
export const setAttr = dom.setAttr;
export const removeAttr = dom.removeAttr;
export const getAttr = dom.getAttr;
export const hasAttr = dom.hasAttr;
export const getBCR = dom.getBCR;
export const getCS = dom.getCS;
export const offset = dom.offset;

0 comments on commit e0a4444

Please sign in to comment.