解析源码,重写window.alert()方法
解析源码,重写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;
}
使用
- 赋值给window.alert -> window.alert = alert
- 使用 -> alert(msg,fun)
效果展示
原效果:
原alert有域名,且无法接受函数
重写后:
我们重写后,可以随便添加样式,可以接受函数后续如果还需要添加内容,或者需要触发回调函数,甚至在弹框内添加背景图片都可以实现。
终!
转载自:https://juejin.cn/post/7244818841502793785