百度前端学院之听UI组件之浮出层

前言

今天抽点时间把之前写的东西贴出来。

正文

imgn

这次的任务是做一个浮出层的UI组件。

要求如下: 浮出层的中心默认在屏幕正中 当浮出层显示时,屏幕滚动时,浮出层始终保持位置固定在屏幕正中,不随屏幕滚动而变化位置。或者禁止页面在有浮出层出现时滚动 当浮出层显示时,点击浮出层以外的部分,默认为关闭浮出层。可以实现一个半透明的遮罩来挡住浮出层外的部分 浮出层的样式、内容和逻辑尽量解耦 提供使用JavaScript控制浮出层展现和关闭的接口 浮出层的窗口大小可以是一个默认固定值,也可以是随内容变化而自适应变化,也可以是通过接口参数进行调整,自行根据自己能力进行选择 有能力的同学可以实现浮出层的拖拽移动浮出窗口位置以及拖拽边缘来放大缩小浮出窗口的功能

除了拖拽的以及附近那块内容,我把其它基础功能实现了。

下面直接来代码:

html:
		<button class="toggle">展示/隐藏</button>
    <div class="modal hide" id="modal">
    		<div class="overlay-mask" id="overlay-mask"></div>
        <div class="modal-dialog">
            <div class="modal-content">
                <div class="modal-header">
                    <button type="button" class="close"><span aria-hidden="true">&times;</span></button>
                    <h4 class="modal-title">这是一个浮动层</h4>
                </div>
                <div class="modal-body">
                    <p>这是一个浮出层</p>
                </div>
                <div class="modal-footer">
                    <button type="button" class="btn btn-primary modal-func" data-dismiss="modal">确定</button>
                    <button type="button" class="btn btn-default modal-cancel">取消</button>
                </div>
            </div>
            <!-- /.modal-content -->
        </div>
        <!-- /.modal-dialog -->
    </div>

样式我直接去拖bootstrap相关css样式。关于遮罩这在我之前的博文里有提到,我这里直接拿过来用。

css:
body {
    height: 100%;
}

.overlay-mask {
    position: absolute;
    left: 0;
    top: 0;
    width: 100%;
    height: 100%;
    z-index: 15;
    cursor: pointer;
}
.hide {
    display: none!important;
}

.modal {
    position: fixed;
    top: 0;
    right: 0;
    bottom: 0;
    left: 0;
    z-index: 10;
    overflow: hidden;
    -webkit-overflow-scrolling: touch;
    outline: 0;
    /* width: 600px; */
    margin: 0 auto;
    display: flex;
    height: 100%;
    /* border: 1px solid red; */
    justify-content: center;
    align-items: center;
}

.modal-open .modal {
    overflow-x: hidden;
    overflow-y: auto;
}

.modal-dialog {
    position: relative;
    width: auto;
    margin: 10px;
    width: 600px;
    z-index: 20;
}

.modal .close {
    float: right;
    font-size: 21px;
    font-weight: 700;
    line-height: 1;
    color: #000;
    text-shadow: 0 1px 0 #fff;
    filter: alpha(opacity=20);
    opacity: .2;
}

.modal-content {
    position: relative;
    background-color: #fff;
    -webkit-background-clip: padding-box;
    background-clip: padding-box;
    border: 1px solid #999;
    border: 1px solid rgba(0, 0, 0, .2);
    border-radius: 6px;
    outline: 0;
    -webkit-box-shadow: 0 3px 9px rgba(0, 0, 0, .5);
    box-shadow: 0 3px 9px rgba(0, 0, 0, .5)
}

.modal-backdrop {
    position: fixed;
    top: 0;
    right: 0;
    bottom: 0;
    left: 0;
    z-index: 1040;
    background-color: #000
}

.modal-backdrop .fade {
    filter: alpha(opacity=0);
    opacity: 0
}

.modal-backdrop .in {
    filter: alpha(opacity=50);
    opacity: .5
}

.modal-header {
    min-height: 16.43px;
    padding: 15px;
    border-bottom: 1px solid #e5e5e5
}

.modal-header .close {
    margin-top: -2px
}

.modal-title {
    margin: 0;
    line-height: 1.42857143
}

.modal-body {
    position: relative;
    padding: 15px
}

.modal-footer {
    padding: 15px;
    text-align: right;
    border-top: 1px solid #e5e5e5
}

.modal-footer .btn+.btn {
    margin-bottom: 0;
    margin-left: 5px
}

.modal-footer .btn-group .btn+.btn {
    margin-left: -1px
}

.modal-footer .btn-block+.btn-block {
    margin-left: 0
}

.modal-scrollbar-measure {
    position: absolute;
    top: -9999px;
    width: 50px;
    height: 50px;
    overflow: scroll
}

之后就是写Js,考虑到需要以后扩展以及自定义事件,因此还是使用之前的设计模式.

js:

window.onload = function() {
    var data = {
        title: '这是测试标题',
        content: '这是测试里的内容',
        type: 'default',
        func: function() {
            console.log("2333");
        },
    };
    modal(data);

    function modal(data) {
        var config = data;
            console.log(data);
        var modalBox = {
            modalConfig: {
                title: config.title || '默认标题', // modal标题
                content: config.content || '这是默认的内容', // modal内容
                //type: config.type, // modal类型
                func: config.func || 0, // 其他处理方法
            },
            //modal显示/隐藏
            toggle: function() {
                var modal = document.getElementById("modal");
                console.log('show');
                if (modal.className.indexOf('hide')) {
                    modal.className = 'modal';
                } else {
                    modal.className = 'modal hide';
                }
            },
            init: function() {
                var that = this;
                var modal = document.getElementById("modal");
                //写入配置
                document.querySelector(".modal-title").innerText = that.modalConfig.title;
                document.querySelector(".modal-body").innerText = that.modalConfig.content;
                document.querySelector(".modal-title").innerText = that.modalConfig.title;
                //监听事件
                document.querySelector(".toggle").addEventListener('click', function() {
                    that.toggle();
                }, false);

                //遮罩层隐藏
                document.querySelector("#overlay-mask").addEventListener('click', function() {
                    document.getElementById("modal").className = 'modal hide';

                }, false);
                //取消事件
                document.querySelector(".modal-cancel").addEventListener('click', function() {
                    document.getElementById("modal").className = 'modal hide';
                }, false);

                document.querySelector(".modal-func").addEventListener('click', function() {
                		//如果没有指定处理函数
                    if(that.modalConfig.func == 0){
                    	 document.getElementById("modal").className = 'modal hide';
                    }else{
                    	 that.modalConfig.func();
                    	 document.getElementById("modal").className = 'modal hide';
                    }
                }, false);
            }

        }
        return modalBox.init();
    }


}

结尾

近期的确没有多少时间去做别的事情,等到五月中旬事情全部结束可能会有个小爆发。

Table of Contents