纯js美化alert弹出窗口

纯js实现自定义弹窗,美化alert窗口

纯js美化alert弹窗
众所周知,浏览器自带的原生弹窗很不美观,而且功能比较单一,绝大部分时候我们都会按照设计图自定义弹窗或者直接使用注入layer的弹窗等等。前段时间在慕课网上看到了一个自定义弹窗的实现,自己顺便就学习尝试写了下,下面是主要的实现代码并添加了比较详细的注释,分享出来供大家参考。(代码用了ES6部分写法如需兼容低版本浏览器请把相关代码转成es5写法,后面有时间更新为一个兼容性较好的es5版本)

  1. HTML部分:(没什么内容 放置一个按钮调用函数,js中调用实例即可供参考)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>自定义弹窗</title>
    <link rel="stylesheet" href="alert.css">
    </head>
    <body>

    <button>Click me</button>
    <script src="index.js"></script>
    <script>
    document.querySelector("button").addEventListener("click",()=>{
    new $Msg({
    content:"我的自定义弹窗好了",
    type:"success",
    cancle:function(){
    let cancle = new $Msg({
    content:"我是取消后的回调"
    })
    },
    confirm:function(){
    new $Msg({content:"我是确定后的回调"})
    }
    })
    })

    </script>
    </body>
    </html>
  2. 样式部分:也放出来供参考,样式可以根据自己的设计图自行更改即可

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    /* 弹出框最外层 */
    .msg__wrap {
    position: fixed;
    top: 50%;
    left: 50%;
    z-index: 10;
    transition: all .3s;
    transform: translate(-50%, -50%) scale(0, 0);
    max-width: 50%;

    background: #fff;
    box-shadow: 0 0 10px #eee;
    font-size: 10px;
    }

    /* 弹出框头部 */
    .msg__wrap .msg-header {
    padding: 10px 10px 0 10px;
    font-size: 1.8em;
    }

    .msg__wrap .msg-header .msg-header-close-button {
    float: right;
    cursor: pointer;
    }

    /* 弹出框中部 */
    .msg__wrap .msg-body {
    padding: 10px 10px 10px 10px;
    display: flex;
    }

    /* 图标 */
    .msg__wrap .msg-body .msg-body-icon{
    width: 80px;
    }

    .msg__wrap .msg-body .msg-body-icon div{
    width: 45px;
    height: 45px;
    margin: 0 auto;
    line-height: 45px;
    color: #fff;
    border-radius: 50% 50%;
    font-size: 2em;
    }

    .msg__wrap .msg-body .msg-body-icon .msg-body-icon-success{
    background: #32a323;
    text-align: center;
    }

    .msg__wrap .msg-body .msg-body-icon .msg-body-icon-success::after{
    content: "成";
    }

    .msg__wrap .msg-body .msg-body-icon .msg-body-icon-wrong{
    background: #ff8080;
    text-align: center;
    }

    .msg__wrap .msg-body .msg-body-icon .msg-body-icon-wrong::after{
    content: "误";
    }

    .msg__wrap .msg-body .msg-body-icon .msg-body-icon-info{
    background: #80b7ff;
    text-align: center;
    }

    .msg__wrap .msg-body .msg-body-icon .msg-body-icon-info::after{
    content: "注";
    }

    /* 内容 */
    .msg__wrap .msg-body .msg-body-content{
    min-width: 200px;
    font-size: 1.5em;
    word-break: break-all;
    display: flex;
    align-items: center;
    padding-left: 10px;
    box-sizing: border-box;
    }

    /* 弹出框底部 */
    .msg__wrap .msg-footer {
    padding: 0 10px 10px 10px;
    display: flex;
    flex-direction: row-reverse;
    }

    .msg__wrap .msg-footer .msg-footer-btn {
    width: 50px;
    height: 30px;
    border: 0 none;
    color: #fff;
    outline: none;
    font-size: 1em;
    border-radius: 2px;
    margin-left: 5px;
    cursor: pointer;
    }

    .msg__wrap .msg-footer .msg-footer-cancel-button{
    background-color: #ff3b3b;
    }

    .msg__wrap .msg-footer .msg-footer-cancel-button:active{
    background-color: #ff6f6f;
    }

    .msg__wrap .msg-footer .msg-footer-confirm-button{
    background-color: #4896f0;
    }

    .msg__wrap .msg-footer .msg-footer-confirm-button:active{
    background-color: #1d5fac;
    }

    /* 遮罩层 */
    .msg__overlay {
    position: fixed;
    top: 0;
    right: 0;
    bottom: 0;
    left: 0;
    z-index: 5;
    background-color: rgba(0, 0, 0, .4);
    transition: all .3s;
    opacity: 0;
    }
  3. JS部分:下面是最主要的部分,js方法及交互。自己封装自定义组件均可以此为参考,封装自己的组件。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    /*
    *自定义弹窗
    */
    //自执行函数 形成封闭的作用域 避免全局污染
    //传入windwo和document对象 相当于将window和document作为了作用域中的局部变量,
    //就不需要内部函数沿着作用域链再查找到最顶层的window 提高运行效率。
    (function (window, document) {
    //定义一个构造函数Msg 作为弹窗实例的构造函数。
    let Msg = function (options) {
    //执行初始化操作
    this._init(options);
    }

    //定义初始化方法 并对方法传递的参数进行初始化
    Msg.prototype = {
    _init({
    content = "", //文本内容
    type = "info", //信息类型
    useHTML = false, //是否解析html字符串
    showIcon = true, //是否展示弹窗图标
    confirm = null, //确认后得回调
    cancle = null, //取消后得回调
    footer = true, //是否显示底部的确认按钮
    header = true, //是否显示头部信息及关闭按钮
    title = "提示", //弹窗标题
    contentStyle = {}, //内容样式
    contentFontSize = "1.5em", //内容字体大小
    btnName = ["确定", "取消"] //按钮文字内容
    }) {
    //将传入的值绑定到this上
    this.content = content;
    this.type = type;
    this.useHTML = useHTML;
    this.showIcon = showIcon;
    this.confirm = confirm;
    this.cancle = cancle;
    this.footer = footer;
    this.header = header;
    this.title = title;
    this.contentStyle = contentStyle;
    this.contentFontSize = contentFontSize;
    this.btnName = btnName;

    //执行创建元素方法
    this._creatElement();
    //显示弹窗及遮罩
    this._show({
    el: this._el,
    overlay: this._overlay
    });
    //绑定事件处理函数
    this._bind({
    el: this._el,
    overlay: this._overlay
    });
    },

    //创建弹窗元素方法
    _creatElement() {
    //创建最外层得包裹元素
    let wrap = document.createElement("div");
    wrap.className = "msg__wrap";

    //定义弹窗得两个按钮
    const [confirmBtnName, cancelBtnName] = this.btnName;

    //判断是否显示弹窗标题
    const headerHTML = this.header ?
    `<div class="msg-header">
    <span>${this.title}</span>
    <span class="msg-header-close-button">×</span>
    </div>` : "";

    //判断是否显示图标
    const iconHTML = this.showIcon ?
    `<div class="msg-body-icon">
    <div class="msg-body-icon-${this.type}"></div>
    </div>` : "";

    //判断是否显示弹窗底部按钮
    const footerHTML = this.footer ?
    `<div class="msg-footer">
    <button class="msg-footer-btn msg-footer-cancel-button">${cancelBtnName}</button>
    <button class="msg-footer-btn msg-footer-confirm-button">${confirmBtnName}</button>
    </div>` : "";

    //拼接完整html
    const innerHTML = `${headerHTML}
    <div class="msg-body">
    ${iconHTML}
    <div class="msg-body-content"></div>
    </div>
    ${footerHTML}`;

    //将拼接的html赋值到wrap中
    wrap.innerHTML = innerHTML;

    //把自定义的样式进行合并
    const contentStyle = {
    fontSize: this.contentFontSize,
    ...this.contentStyle
    }

    //获取内容所属DOM
    let content = wrap.querySelector(".msg-body .msg-body-content");
    //将传过来的样式添加到contentDOM
    for (const key in contentStyle) {
    if (contentStyle.hasOwnProperty(key)) {
    content.style[key] = contentStyle[key];

    }
    }

    //给弹窗的conntent赋值
    if (this.useHTML) {
    content.innerHTML = this.content;
    } else {
    content.innerText = this.content;
    }

    //创建遮罩层
    let overlay = document.createElement("div");
    overlay.className = "msg__overlay";

    //把dom挂载到当前实例上
    this._overlay = overlay;
    this._el = wrap;
    },

    //弹窗展现方法
    _show({
    el,
    overlay
    }) {
    //把弹窗的dom和遮罩插入到页面中
    document.body.appendChild(el);
    document.body.appendChild(overlay);

    //将弹窗显示出来 timeout进行异步处理显示动画
    setTimeout(() => {
    el.style.transform = "translate(-50%,-50%) scale(1,1)";
    overlay.style.opacity = "1";
    })
    },

    //关闭弹窗方法
    _close({
    el,
    overlay
    }) {
    //隐藏dom
    el.style.transform = "translate(-50%,-50%) scale(0,0)";
    overlay.style.opcity = "0";
    //根据动画时间 动画完成再移除
    setTimeout(() => {

    //把弹窗的dom和遮罩移除
    document.body.removeChild(el)
    document.body.removeChild(overlay);
    }, 300);
    },

    //事件处理函数,为DOM绑定事件
    _bind({
    el,
    overlay
    }) {
    //保存当前this
    //const _this = this;

    const cancle = (e) => {
    this.cancle && this.cancle.call(this, e);
    //隐藏弹窗
    //hideMsg();
    this._close({
    el,
    overlay
    });
    }
    //确认弹窗
    const confirm = (e) => {
    this.confirm && this.confirm.call(this, e);
    this._close({
    el,
    overlay
    });
    }


    //顶部关闭按钮绑定事件
    if (this.header) {
    el.querySelector(".msg-header-close-button").addEventListener("click", cancle);
    }
    //弹窗底部两个按钮事件监听
    if (this.footer) {
    el.querySelector(".msg-footer-cancel-button").addEventListener("click", cancle);
    el.querySelector(".msg-footer-confirm-button").addEventListener("click", confirm)
    }
    }


    }

    //将构造函数暴露到window 可直接在全局作用域中访问构造函数
    window.$Msg = Msg;


    })(window, document);

    到此,一个完整的自定义弹窗组件已完成,只需要引入该js以及css或者直接把相关代码加到自己的公共js中即可直接调用,注意,构造函数调用要用new.

转自

https://www.cnblogs.com/websharehome/p/9438741.html

-------------本文已结束赏个小钱吧-------------
×

感谢您的支持,我们会一直保持!

扫码支持
请土豪扫码随意打赏

打开微信扫一扫,即可进行扫码打赏哦

分享从这里开始,精彩与您同在

64.7K

相关文章推荐