JS实现自定义弹窗功能

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

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

<!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" rel="external nofollow" >

</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>

样式部分:也放出来供参考,样式可以根据自己的设计图自行更改即可

/* 弹出框最外层 */

.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;

}

JS部分:下面是最主要的部分,js方法及交互。自己封装自定义组件均可以此为参考,封装自己的组件。

/*

*自定义弹窗

*/

//自执行函数 形成封闭的作用域 避免全局污染

//传入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.

总结

以上所述是小编给大家介绍的JS实现自定义弹窗功能,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对网站的支持!

以上是 JS实现自定义弹窗功能 的全部内容, 来源链接: utcz.com/z/339701.html

回到顶部