前言:在写页面时经常会有点击一个按钮弹出一个模态框的需求,Bootstrap的模态框只有固定margin-top,故想自己写一个,在此整理下学习过程中的一些问题。

1. 根据模态框内容高度决定模态框是垂直居中显示还是固定margin-top居中显示

  • 当模态框高度小于浏览器可视高度时,模态框垂直居中显示
  • 当模态框高度大于浏览器可视高度时,采用固定margin-top、margin-bottom和左右auto居中显示
CSS

/*若模态框高度小于浏览器可视高度则采用js计算margin-top形式垂直居中显示*/
.modal-mar-type1 {
  position: relative;
  margin: 0 auto;
}
/*若模态框高度大于浏览器可视高度则采用固定margin-top形式显示模态框*/
.modal-mar-type2 {
  position: relative;
  margin: 0 auto;
  margin-top: 100px;
  margin-bottom: 100px;
}
JS

// 浏览器可视高度
var browserHeight = window.innerHeight;
// 模态框高度
var height = $("." + id + "-modal").children(".modal-wrapper").height();

if (height > browserHeight) {
    $(that.preModal).css("overflow", "auto");
    $(that.preModal).children(".modal-wrapper").removeClass("modal-mar-type1");
    $(that.preModal).children(".modal-wrapper").addClass("modal-mar-type2");
} else {
    $(that.preModal).children(".modal-wrapper").removeClass("modal-mar-type2");
    $(that.preModal).children(".modal-wrapper").addClass("modal-mar-type1");
    $(that.preModal).children(".modal-wrapper").css("margin-top", (browserHeight - height) / 2 + "px");
}

2. 点击关闭按钮和点击遮罩层进而关闭模态框

  • 问题:在设置点击遮罩层时,会出现点击模态框本身也会关闭的情况
  • 解决:阻止事件冒泡
$("[data='close'], .modal").on("click", function() {
  modal.hide('className');
});

$('.modal-wrapper').on('click', function(e) {
  e.stopPropagation();
})

3. 滚动穿透问题

  • 问题:网页内容过多时会出现滚动条,此时弹出模态框,若模态框内容较少垂直居中显示,则滚动的是body的内容,若模态框内容较多,则滚动的还是body内容,且此时模态框内容被遮挡。
  • 解决:在弹出模态框时,设置body的overflow-y: hidden,设置模态框的overflow-y: auto;

20190114更新

  • 解决:经过测试以上方法在pc可以,但是移动端无效,改为在弹出模态框时,为body添加样式open-modal如下:
.modal-open {
  position: fixed;
  width: 100%;
  box-sizing: border-box;//避免第4点中设置padding-left导致body宽度增加
}

由于在设置body为fixed时,页面回回到顶部,需在js中设置页面滚动:

// 开启模态框前记录页面滚动距离
var scrollTop = document.body.scrollTop;

// 开启模态框时设置如下
document.body.style.top = -scrollTop + "px";

// 关闭模态框时移除open-modal类名的同时设置如下
document.body.scrollTop = scrollTop;

4. body宽度改变

  • 问题:在overflow-y: hidden与auto切换时body宽度会改变,体验较差
  • 解决:在overflow-y: hidden与auto切换时动态设置body的padding-left

20190114更新

  • 问题:在body切换fixed时宽度会改变,体验较差
  • 解决:在body切换fixed时动态设置body的padding-left
scrollWidth = window.innerWidth - document.body.clientWidth;
$('body').css('padding-right', scrollWidth + 'px');

5. 渐隐渐现效果

  • 问题:CSS3动画在display: none时是没有效果的,而以上的模态框是通过控制display进行显示的
  • 解决:利用定时器,在设置display: none之前和display: block之后进行动画设置

6. iOS以及微信下模态框中含有输入框时的相关BUG

参考iOS光标错位以及微信页面不回弹问题

. 参考资料

. 源码

分类: 前端

发表评论

电子邮件地址不会被公开。 必填项已用*标注