likes
comments
collection
share

解析源码,重写window.alert()方法

作者站长头像
站长
· 阅读数 63

解析源码,重写window.alert()方法

背景

项目最近有个要求用户在流程中点击提交按钮,出现弹窗提示,当用户关闭弹窗后,再次点击提交按钮,不提示弹窗,相当于:用户点击->弹窗->用户关闭弹窗->用户再次点击->提交流程

懒得写弹窗,想着alert()不也是弹窗吗?干脆用alert()代替弹窗算了,得到领导默许后,就开始研究,发现alert()会出现当前网页的域名,领导要求专研一下,去掉域名,那我郁闷了,改写源码呗。

思考

弹窗只有当前流程需要,其他使用alert()的地方不能改变,所以我需要保存原alert()->修改alert()->调用新的alert()->还原alert()

最难的地方是修改alert(),因为找了好久没找到window.alert()源码,干脆不沿用原码了,自己重新写一个。

window.alert()


//重写alert
function alert(data, callback) { //回调函数,data -> alert函数的值 -> alert(data)
    console.log(data);
    // 创建新的元素
    var alert_bg = document.createElement('div'),// 背景蒙版
        alert_box = document.createElement('div'),// 背景弹框
        alert_text = document.createElement('div'),// 承载data的div
        alert_btn = document.createElement('div'),// 点击按钮
        textNode = document.createTextNode(data ? data : ''),// 用户向alert()传值时,例:alert(data),赋值给textNode
        btnText = document.createTextNode('确 定');

    // 元素的css样式
    css(alert_bg, {
        'position': 'fixed',
        'top': '0',
        'left': '0',
        'right': '0',
        'bottom': '0',
        'background-color': 'rgba(0, 0, 0, 0.1)',
        'z-index': '999999999'
    });

    css(alert_box, {
        'width': '270px',
        'max-width': '90%',
        'font-size': '16px',
        'text-align': 'center',
        'background-color': '#fff',
        'border-radius': '5px',
        'position': 'absolute',
        'top': '15%',
        'left': '50%',
        'transform': 'translate(-50%, -50%)'
    });

    css(alert_text, {
        'padding': '30px 15px'
    });

    css(alert_btn, {
        'padding': '10px 0',
        'width': '80px',
        'float': 'right',
        'color': '#007aff',
        'font-weight': '600',
        'cursor': 'pointer'
    });

    // 内部结构套入
    // 套盒子:
    // 提示信息套进alert_text
    alert_text.appendChild(textNode);
    // "确定"套进alert_btn
    alert_btn.appendChild(btnText);
    // 再套进alert弹框
    alert_box.appendChild(alert_text);
    alert_box.appendChild(alert_btn);
    // 最后套进蒙版(蒙版:防止用户点击其他地方)
    alert_bg.appendChild(alert_box);

    // 整体显示到页面内(把弹框挂载到页面上)
    document.getElementsByTagName('body')[0].appendChild(alert_bg);

    // 确定绑定点击事件删除标签
    alert_btn.onclick = function () {
        alert_bg.parentNode.removeChild(alert_bg);
        if (typeof callback === 'function') {
            callback(); //回调
        }
    }
}

alert()的样式

因为需要对多个元素调整css参数,所以写了一个公用方法

// targetObj:dom元素
// cssObj:css参数
// 作用:向dom元素写入css参数
function css(targetObj, cssObj) {
    var str = targetObj.getAttribute("style") ? targetObj.getAttribute('style') : '';
    for (var i in cssObj) {
        str += i + ':' + cssObj[i] + ';';
    }
    targetObj.style.cssText = str;
}

使用

  1. 赋值给window.alert -> window.alert = alert
  2. 使用 -> alert(msg,fun)

效果展示

原效果:

解析源码,重写window.alert()方法 原alert有域名,且无法接受函数

重写后:

解析源码,重写window.alert()方法

解析源码,重写window.alert()方法

我们重写后,可以随便添加样式,可以接受函数后续如果还需要添加内容,或者需要触发回调函数,甚至在弹框内添加背景图片都可以实现。

终!

转载自:https://juejin.cn/post/7244818841502793785
评论
请登录