一、 問題描述
移動端當position:fixed
的彈窗彈出時,滑動彈窗,下層的頁面會跟隨滾動
二、 解決方案
1. body
設定overflow: hidden;
當彈窗彈出時,設定body
元素的overflow
屬性為hidden
,暴力去除滾動。
缺點:會丟失頁面的滾動位置,需要使用js進行還原
// CSS
.modal-open {
overflow: hidden;
height: 100%;
}
複製程式碼
// JS
let modalManager = (function() {
return {
scrollTop: 0,
getScrollTop() {
return document.body.scrollTop || document.documentElement.scrollTop
},
scrollTo(position) {
document.body.scrollTop = document.documentElement.scrollTop = position
},
show(ele) {
this.scrollTop = this.getScrollTop()
document.querySelector(ele).style.display = 'block'
document.body.classList.add('modal-open')
this.scrollTo(this.scrollTop)
},
hide(ele) {
document.querySelector(ele).style.display = 'none'
document.body.classList.remove('modal-open')
this.scrollTop = 0
}
}
})();
複製程式碼
2. body
設定position: fixed;
當彈窗彈出時,設定body
元素的positon
屬性為fixed
,使其脫離文件流,去除滾動。
缺點:會丟失頁面的滾動位置,需要使用js進行還原
// CSS
.modal-open {
position: fixed;
width: 100%;
}
複製程式碼
// JS
let modalManager = (function() {
return {
scrollTop: 0,
// 彈窗數量
modalNum: 0,
getScrollTop() {
return document.body.scrollTop || document.documentElement.scrollTop
},
// body脫離文件流,通過設定其top屬性來恢復滾動位置
scrollTo(position) {
document.body.style.top = -position + 'px'
},
show(ele) {
// 與第一種方法不同的是,body脫離文件流時,讀取不到scrollTop,所以同時彈出多個彈窗的時候,不用重新讀取scrollTop
if (this.modalNum <= 0) {
this.scrollTop = this.getScrollTop()
document.body.classList.add('modal-open')
this.scrollTo(this.scrollTop)
}
document.querySelector(ele).style.display = 'block'
this.modalNum++
},
hide(ele) {
if (this.modalNum <= 1) {
document.body.classList.remove('modal-open')
document.body.scrollTop = document.documentElement.scrollTop = this.scrollTop
this.scrollTop = 0
}
document.querySelector(ele).style.display = 'none'
this.modalNum = this.modalNum >= 1 ? this.modalNum - 1 : 0
}
}
})();
複製程式碼
3. 阻止彈窗的touchmove預設事件
缺點:導致彈窗內部也無法滾動,適用於彈窗內無滾動內容的情況
document.querySelector('.modal').addEventListener('touchmove', e => {
e = e || window.event
e.preventDefault()
}, false)
複製程式碼