首页 > 编程 > JavaScript > 正文

JS实现自定义弹窗功能

2019-11-19 13:19:20
字体:
来源:转载
供稿:网友

众所周知,浏览器自带的原生弹窗很不美观,而且功能比较单一,绝大部分时候我们都会按照设计图自定义弹窗或者直接使用注入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实现自定义弹窗功能,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对武林网网站的支持!

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表