獲取瀏覽器滾動條寬度,一般用於彈出層的時候,設置body
的右邊距,防止overflow: hidden
的時候元素抖動。
scrollbar-width.js
import Vue from 'vue';
let scrollBarWidth;
export default function() {
// 如果是服務器端渲染,則瀏覽器滾動條的寬度爲0
if (Vue.prototype.$isServer) return 0;
if (scrollBarWidth !== undefined) return scrollBarWidth;
const outer = document.createElement('div');
outer.className = 'el-scrollbar__wrap';
// 強制出現滾動條
// .el-scrollbar__wrap {
// overflow: scroll;
// height: 100%
// }
outer.style.visibility = 'hidden';
outer.style.width = '100px';
outer.style.position = 'absolute';
outer.style.top = '-9999px';
document.body.appendChild(outer);
// https://developer.mozilla.org/zh-CN/docs/Web/API/HTMLElement/offsetWidth
const widthNoScroll = outer.offsetWidth;
outer.style.overflow = 'scroll';
const inner = document.createElement('div');
inner.style.width = '100%';
outer.appendChild(inner);
const widthWithScroll = inner.offsetWidth;
outer.parentNode.removeChild(outer);
// 父元素出現滾動條,子元素無滾動條,父元素減去子元素的寬度就是滾動條寬度
scrollBarWidth = widthNoScroll - widthWithScroll;
return scrollBarWidth;
};
簡單使用
let scrollBarWidth;
export default function() {
const outer = document.createElement('div');
outer.style.overflow = 'scroll';
outer.style.visibility = 'hidden';
outer.style.width = '100px';
outer.style.height = '100%';
outer.style.position = 'absolute';
outer.style.top = '-9999px';
document.body.appendChild(outer);
// https://developer.mozilla.org/zh-CN/docs/Web/API/HTMLElement/offsetWidth
const widthNoScroll = outer.offsetWidth;
const inner = document.createElement('div');
inner.style.width = '100%';
outer.appendChild(inner);
const widthWithScroll = inner.offsetWidth;
outer.parentNode.removeChild(outer);
// 父元素出現滾動條,子元素無滾動條,父元素減去子元素的寬度就是滾動條寬度
scrollBarWidth = widthNoScroll - widthWithScroll;
return scrollBarWidth;
};
彈窗彈出時如果需要鎖屏(鎖住彈窗下的頁面不滾動),則加上下面這段代碼,彈窗彈出時鎖屏,彈窗關閉時再將其去除。
// 如果需要鎖屏(鎖住彈窗下的頁面不滾動)
if (props.lockScroll) {
// body 上面是否添加 'el-popup-parent--hidden'
// .el-popup-parent--hidden {
// overflow: hidden
// }
this.withoutHiddenClass = !hasClass(document.body, 'el-popup-parent--hidden');
if (this.withoutHiddenClass) {
// 獲取 body 的 paddingRight
this.bodyPaddingRight = document.body.style.paddingRight;
this.computedBodyPaddingRight = parseInt(getStyle(document.body, 'paddingRight'), 10);
}
// 獲取滾動條寬
scrollBarWidth = getScrollBarWidth();
// body 是否出現滾動條
let bodyHasOverflow = document.documentElement.clientHeight < document.body.scrollHeight;
// body 的 overflowY 設置值
let bodyOverflowY = getStyle(document.body, 'overflowY');
if (scrollBarWidth > 0 && (bodyHasOverflow || bodyOverflowY === 'scroll') && this.withoutHiddenClass) {
// body 的 paddingRight 加上 滾動條寬度來實現防止頁面抖動
document.body.style.paddingRight = this.computedBodyPaddingRight + scrollBarWidth + 'px';
}
// body 添加 overflow: hidden
addClass(document.body, 'el-popup-parent--hidden');
}
彈窗關閉時將彈窗打開時設置的值去除。
if (tthis.withoutHiddenClass) {
document.body.style.paddingRight = this.bodyPaddingRight;
removeClass(document.body, 'el-popup-parent--hidden');
}
this.withoutHiddenClass = true;
文中的一些方法可以查看Element-UI / dom.js 的學習。
更多內容可查看我的個人博客。