单独封装alert和comfirm

2019-06-09  本文已影响0人  smallzip

说明:单独封装alert和comfirm可以保持设计稿的ui,顺便兼容其他浏览器保持ui统一。

思路:直接覆盖浏览器默认的alert和confirm方法

<!DOCTYPE html>
<html lang="en">

<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>测试4</title>
</head>
<style>
    body {
        background-image: url(http://www.cnr.cn/xjfw/btfw/2011btfw/jkwh/jkwt/20160516/W020160516492035673595.jpg);
        background-repeat: none;
        background-size: auto;
    }

    #alert-eject-frame-mask {
        position: fixed;
        top: 0;
        left: 0;
        right: 0;
        bottom: 0;
        background-color: rgba(255, 255, 255, .4);
        z-index: 2147483646;
    }

    #alert-eject-frame-content {
        position: absolute;
        top: 42%;
        left: calc(50% - 120px);
        width: 240px;
        background-color: #fff;
        z-index: 2147483647;
        border-radius: 5px;
        text-align: center;
        animation: showAlert .5s ease;
        -webkit-animation: showAlert .5s ease;
    }

    @keyframes showAlert {
        from {
            opacity: 0;
            transform: scale(0);
        }

        to {
            opacity: 1;
            transform: scale(1);
        }
    }

    @-webkit-keyframes showAlert

    /*Safari and Chrome*/
        {
        from {
            opacity: 0;
            transform: scale(0);
        }

        to {
            opacity: 1;
            transform: scale(1);
        }
    }

    @keyframes hideAlert {
        from {
            opacity: 1;
            transform: scale(1);
        }

        to {
            opacity: 0;
            transform: scale(0);
        }
    }

    @-webkit-keyframes hideAlert

    /*Safari and Chrome*/
        {
        from {
            opacity: 1;
            transform: scale(1);
        }

        to {
            opacity: 0;
            transform: scale(0);
        }
    }

    .alert-eject-frame-txt {
        padding: 20px;
        font-size: 1.04rem;
    }

    .alert-eject-frame-buttom-cancel {
        height: 50px;
        line-height: 50px;
        border-top: 1px solid #e5e5e5;
        font-size: 1.04rem;
        color: rgb(105, 101, 101);
        cursor: pointer;
    }

    .alert-eject-frame-buttom-flex {
        display: flex;
        height: 50px;
        line-height: 50px;
        border-top: 1px solid #e5e5e5;
        font-size: 1.04rem;
        color: rgb(105, 101, 101);
        cursor: pointer;
    }

    .alert-eject-frame-buttom-flex div {
        flex: 1;
    }

    .alert-eject-frame-buttom-flex div:nth-child(1) {
        border-right: 1px solid #e5e5e5;
    }
</style>

<body>
    <div onclick="openAlert('默认alert')">默认alert</div>
    <br />
    <br />
    <div onclick="alert('alert点击遮罩也可以关闭',null,null,1,null)">alert点击遮罩也可以关闭</div>
    <br />
    <br />
    <div onclick="alert('alert自定义弹框宽度',null,null,1,400)">alert自定义弹框宽度</div>
    <br />
    <br />
    <div onclick="openConfirm('默认confirm')">默认confirm</div>
    <br />
    <br />
    <div onclick="openConfirm('confirm点击遮罩也可以关闭',null,1)">confirm点击遮罩也可以关闭</div>
    <br />
    <br />
    <div onclick="openConfirm('confirm自定义弹框宽度',null,1,400)">confirm自定义弹框宽度</div>
</body>

<script>
    function openAlert(txt, callback) {
        alert(txt,(i) => {
            //  执行回调
        })
    }

    function openConfirm(txt, btn,closeMask, alertWidth) {
        confirm(txt,(e) =>{
            e ? alert(`点击了确认`) : alert(`点击了取消`)
        }, closeMask, alertWidth)
    }


    //  事件回调
    let eventCallBack = null

    /*
    *  txt:必填,要显示的内容
    *  callback:回调
    *  confirm:确认按钮
    *  closeMask:点击遮罩也可以关闭
    *  lertWidth: 弹框宽度
    */
    window.alert = function (txt, callback, confirm, closeMask, alertWidth) {
        eventCallBack = callback
        //  是否需要确认按钮
        let confirmHTML = ``
        if (confirm) {
            confirmHTML = `
            <div class="alert-eject-frame-buttom-flex">
                <div onclick="closeAlertEjectFrame(false)">取消</div>
                <div onclick="closeAlertEjectFrame(true)">确认</div>
            </div>`
        } else {
            confirmHTML = `<div onclick="closeAlertEjectFrame(false)" class="alert-eject-frame-buttom-cancel">取消</div>`
        }

        //  body插入节点
        CADN(`body`).innerHTML += `
            <div id="alert-eject-frame-mask" ${closeMask ? `onclick="closeAlertEjectFrame()"` : ``}></div>
            <div id="alert-eject-frame-content">
                <div class="alert-eject-frame-txt">${txt}</div>
                ${confirmHTML}
            </div>
            `
        //  计算弹框宽高使之居中
        alertEjectFrameSettimeout(alertWidth)
    }


    /*
    *  txt:必填,要显示的内容
    *  btn:确认/取消按钮 方法名称
    *  closeMask:点击遮罩也可以关闭
    *  lertWidth: 弹框宽度
    */
    window.confirm = function (txt, btn, closeMask, alertWidth) {
        eventCallBack = btn
        //  body插入节点
        CADN(`body`).innerHTML += `
            <div id="alert-eject-frame-mask" ${closeMask ? `onclick="closeAlertEjectFrame()"` : ``}></div>
            <div id="alert-eject-frame-content">
                <div class="alert-eject-frame-txt">${txt}</div>
                <div class="alert-eject-frame-buttom-flex">
                    <div onclick="closeAlertEjectFrame(false)">取消</div>
                    <div onclick="closeAlertEjectFrame(true)">确认</div>
                </div>
            </div>
            `
        //  计算弹框宽高使之居中
        alertEjectFrameSettimeout(alertWidth)
    }

    //  计算弹框宽高,居中布局
    function alertEjectFrameSettimeout(alertWidth) {
        setTimeout(() => {
            let domHeight = CADN().clientHeight                                                     //  弹框高度
            let screenHeight = document.documentElement.clientHeight || document.body.clientHeight  //  浏览器可视区域高度
            CADN().style.top = `${(screenHeight - domHeight) / 2}px`                                //  使得弹框垂直居中
            if (alertWidth) {                                                                       //  弹框宽度
                let screenWidth = document.documentElement.clientWidth || document.body.clientWidth //  浏览器可视区域高度
                CADN().style.width = `${alertWidth}px`                                              //  设置弹框宽度
                CADN().style.left = `${(screenWidth - alertWidth) / 2}px`                           //  弹框垂直居中
            }
        }, 0);
    }

    function CADN(i) {
        return i ? document.querySelector(i) : document.querySelector(`#alert-eject-frame-content`)
    }

    //  关闭弹窗
    function closeAlertEjectFrame(i) {
        i ? eventCallBack&& eventCallBack(true) : eventCallBack&& eventCallBack(false)             //  回调参数为布尔值
        eventCallBack = null                                                                        //  清空回调
        CADN(`#alert-eject-frame-content`).style.animation = `hideAlert .4s ease`                   //  执行影藏动画
        CADN(`#alert-eject-frame-mask`).remove()                                                    //  关闭遮罩层
        setTimeout(() => {                                                                          //  等待影藏动画执行完毕关闭弹框
            CADN(`#alert-eject-frame-content`).remove()
        }, 350);
    }

</script>
</html>

效果如下图↓

alert.gif

可以把文件拆分成公用的js和css,在项目中全局使用

命名为alert.js

//  事件回调
let eventCallBack = null

/*
*  txt:必填,要显示的内容
*  callback:回调
*  confirm:确认按钮
*  closeMask:点击遮罩也可以关闭
*  lertWidth: 弹框宽度
*/
window.alert = function (txt, callback, confirm, closeMask, alertWidth) {
    eventCallBack = callback
    //  是否需要确认按钮
    let confirmHTML = ``
    if (confirm) {
        confirmHTML = `
            <div class="alert-eject-frame-buttom-flex">
                <div onclick="closeAlertEjectFrame(false)">取消</div>
                <div onclick="closeAlertEjectFrame(true)">确认</div>
            </div>`
    } else {
        confirmHTML = `<div onclick="closeAlertEjectFrame(false)" class="alert-eject-frame-buttom-cancel">取消</div>`
    }

    //  body插入节点
    CADN(`body`).innerHTML += `
            <div id="alert-eject-frame-mask" ${closeMask ? `onclick="closeAlertEjectFrame()"` : ``}></div>
            <div id="alert-eject-frame-content">
                <div class="alert-eject-frame-txt">${txt}</div>
                ${confirmHTML}
            </div>
            `
    //  计算弹框宽高使之居中
    alertEjectFrameSettimeout(alertWidth)
}


/*
*  txt:必填,要显示的内容
*  btn:确认/取消按钮 方法名称
*  closeMask:点击遮罩也可以关闭
*  lertWidth: 弹框宽度
*/
window.confirm = function (txt, btn, closeMask, alertWidth) {
    eventCallBack = btn
    //  body插入节点
    CADN(`body`).innerHTML += `
            <div id="alert-eject-frame-mask" ${closeMask ? `onclick="closeAlertEjectFrame()"` : ``}></div>
            <div id="alert-eject-frame-content">
                <div class="alert-eject-frame-txt">${txt}</div>
                <div class="alert-eject-frame-buttom-flex">
                    <div onclick="closeAlertEjectFrame(false)">取消</div>
                    <div onclick="closeAlertEjectFrame(true)">确认</div>
                </div>
            </div>
            `
    //  计算弹框宽高使之居中
    alertEjectFrameSettimeout(alertWidth)
}

//  计算弹框宽高,居中布局
function alertEjectFrameSettimeout(alertWidth) {
    setTimeout(() => {
        let domHeight = CADN().clientHeight                                                     //  弹框高度
        let screenHeight = document.documentElement.clientHeight || document.body.clientHeight  //  浏览器可视区域高度
        CADN().style.top = `${(screenHeight - domHeight) / 2}px`                                //  使得弹框垂直居中
        if (alertWidth) {                                                                       //  弹框宽度
            let screenWidth = document.documentElement.clientWidth || document.body.clientWidth //  浏览器可视区域高度
            CADN().style.width = `${alertWidth}px`                                              //  设置弹框宽度
            CADN().style.left = `${(screenWidth - alertWidth) / 2}px`                           //  弹框垂直居中
        }
    }, 0);
}

function CADN(i) {
    return i ? document.querySelector(i) : document.querySelector(`#alert-eject-frame-content`)
}

//  关闭弹窗
function closeAlertEjectFrame(i) {
    i ? eventCallBack && eventCallBack(true) : eventCallBack && eventCallBack(false)             //  回调参数为布尔值
    eventCallBack = null                                                                        //  清空回调
    CADN(`#alert-eject-frame-content`).style.animation = `hideAlert .4s ease`                   //  执行影藏动画
    CADN(`#alert-eject-frame-mask`).remove()                                                    //  关闭遮罩层
    setTimeout(() => {                                                                          //  等待影藏动画执行完毕关闭弹框
        CADN(`#alert-eject-frame-content`).remove()
    }, 350);
}

命名为alert.css

    #alert-eject-frame-mask {
        position: fixed;
        top: 0;
        left: 0;
        right: 0;
        bottom: 0;
        background-color: rgba(255, 255, 255, .4);
        z-index: 2147483646;
    }
    
    #alert-eject-frame-content {
        position: absolute;
        top: 42%;
        left: calc(50% - 120px);
        width: 240px;
        background-color: #fff;
        z-index: 2147483647;
        border-radius: 5px;
        text-align: center;
        animation: showAlert .5s ease;
        -webkit-animation: showAlert .5s ease;
    }
    
    @keyframes showAlert {
        from {
            opacity: 0;
            transform: scale(0);
        }
        to {
            opacity: 1;
            transform: scale(1);
        }
    }
    
    @-webkit-keyframes showAlert
    /*Safari and Chrome*/
    
    {
        from {
            opacity: 0;
            transform: scale(0);
        }
        to {
            opacity: 1;
            transform: scale(1);
        }
    }
    
    @keyframes hideAlert {
        from {
            opacity: 1;
            transform: scale(1);
        }
        to {
            opacity: 0;
            transform: scale(0);
        }
    }
    
    @-webkit-keyframes hideAlert
    /*Safari and Chrome*/
    
    {
        from {
            opacity: 1;
            transform: scale(1);
        }
        to {
            opacity: 0;
            transform: scale(0);
        }
    }
    
    .alert-eject-frame-txt {
        padding: 20px;
        font-size: 1.04rem;
    }
    
    .alert-eject-frame-buttom-cancel {
        height: 50px;
        line-height: 50px;
        border-top: 1px solid #e5e5e5;
        font-size: 1.04rem;
        color: rgb(105, 101, 101);
        cursor: pointer;
    }
    
    .alert-eject-frame-buttom-flex {
        display: flex;
        height: 50px;
        line-height: 50px;
        border-top: 1px solid #e5e5e5;
        font-size: 1.04rem;
        color: rgb(105, 101, 101);
        cursor: pointer;
    }
    
    .alert-eject-frame-buttom-flex div {
        flex: 1;
    }
    
    .alert-eject-frame-buttom-flex div:nth-child(1) {
        border-right: 1px solid #e5e5e5;
    }

html文件引入

<!DOCTYPE html>
<html lang="en">

<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">
    <link rel="stylesheet" href="alert.css">
    <script src="alert.js"></script>
    <title>测试4</title>
</head>
<style>
    body {
        background-image: url(http://www.cnr.cn/xjfw/btfw/2011btfw/jkwh/jkwt/20160516/W020160516492035673595.jpg);
        background-repeat: none;
        background-size: auto;
    }
</style>

<body>
    <div onclick="openAlert()">测试alert</div>
    <div>测试confirm</div>
</body>

<script>
    function openAlert() {
        alert(`测试内容`)
    }

    function openConfirm() {
        confirm(`测试内容`, (e) => {
            e ? alert(`点击了确认`) : alert(`点击了取消`)
        }, 1, 400)
    }
</script>

</html>

上一篇下一篇

猜你喜欢

热点阅读