博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
一个popup弹窗实现思路--(基于mintui分析)
阅读量:6158 次
发布时间:2019-06-21

本文共 3965 字,大约阅读时间需要 13 分钟。

1667c4be6d1f6f8e?w=337&h=590&f=png&s=13359

1667c4c888fc4da9?w=339&h=585&f=png&s=20329

如何实现一个 messagebox/日期组建/popup

常规实现思路

- 新建一个messagebox组建...- 黑色遮罩封装在messagebox中- 黑色遮罩 加上样式    {        position: fixed:        z-index: 999;        opcity: .6    }    收工~

这样有两个问题

  • 多个弹窗连续弹出的时候 遮罩层会叠加越来越深
  • 如果再有一个类似的其他弹窗(如第二幅图)还要再写一个遮罩,这个时候他们的层级高低容易出现问题

解决方案:参考mintui 的popup实现方法

对黑色弹窗做统一管理 popup-manager.js

关键就再下面两个方法

openModal: function(id, zIndex, dom, modalClass, modalFade) {    if (Vue.prototype.$isServer) return;    if (!id || zIndex === undefined) return;    this.modalFade = modalFade;    const modalStack = this.modalStack;    for (let i = 0, j = modalStack.length; i < j; i++) {      const item = modalStack[i];      if (item.id === id) {        return;      }    }    const modalDom = getModal();    addClass(modalDom, 'v-modal');    if (this.modalFade && !hasModal) {      addClass(modalDom, 'v-modal-enter');    }    if (modalClass) {      let classArr = modalClass.trim().split(/\s+/);      classArr.forEach(item => addClass(modalDom, item));    }    setTimeout(() => {      removeClass(modalDom, 'v-modal-enter');    }, 200);    if (dom && dom.parentNode && dom.parentNode.nodeType !== 11) {      dom.parentNode.appendChild(modalDom);    } else {      document.body.appendChild(modalDom);    }    if (zIndex) {      modalDom.style.zIndex = zIndex;    }    modalDom.style.display = '';    this.modalStack.push({ id: id, zIndex: zIndex, modalClass: modalClass });  },  closeModal: function(id) {    const modalStack = this.modalStack;    const modalDom = getModal();    if (modalStack.length > 0) {      const topItem = modalStack[modalStack.length - 1];      if (topItem.id === id) {        if (topItem.modalClass) {          let classArr = topItem.modalClass.trim().split(/\s+/);          classArr.forEach(item => removeClass(modalDom, item));        }        modalStack.pop();        if (modalStack.length > 0) {          modalDom.style.zIndex = modalStack[modalStack.length - 1].zIndex;        }      } else {        for (let i = modalStack.length - 1; i >= 0; i--) {          if (modalStack[i].id === id) {            modalStack.splice(i, 1);            break;          }        }      }    }        ifIsNested(modalDom)    if (modalStack.length === 0) {      if (this.modalFade) {        addClass(modalDom, 'v-modal-leave');      }      setTimeout(() => {        if (modalStack.length === 0) {          if (modalDom.parentNode) modalDom.parentNode.removeChild(modalDom);          modalDom.style.display = 'none';          PopupManager.modalDom = undefined;        }        removeClass(modalDom, 'v-modal-leave');      }, 200);    }  }};

modal --表示 黑色遮罩

dom -- 表示 黑色遮罩上面的白色内容区域

当打开弹窗的时候主要做两件事

1 手动生成 modal 并添加到modalDom的父节点下 dom.parentNode.appendChild(modalDom);

- modal 的每一个id 唯一- modal 的z-index 每当新生成一个都会自增 - dom的z-index 每当新生成一个都会自增 且比modal的大一- appendChild 有一个重要的属性 如果文档树中已经存在了 newchild,它将从文档树中删除,然后重新插入它的新位置,这个有什么用呢,如下 
如此便能不用手动removechild 同时保证只有一个遮罩,

2 把生成的modal 添加到数组里

当关闭弹窗的时候主要做一件事

1 将遮罩的 z-index改成之前保存在数组里的上一个遮罩的index值

如此基本可以满足大部分需求

然而当 popup 嵌套modal的时候 原库会出现modal位置错误的问题

解决方案也很简单在调用关闭方法的时候调用下面方法

/** * 判断modalDom 是否是再其他 popup中嵌套,如果是嵌套则将modal 移动到最外层modal的父节点下面 * @param {最后一次生成的modalDom} modalDom  */const ifIsNested = function(modalDom) {  if (modalDom) {    if (modalDom.parentNode && modalDom.parentNode !== document.body) {      if (modalDom.parentNode.parentNode && modalDom.parentNode.parentNode.className && modalDom.parentNode.parentNode.className.indexOf('mint-popup') !== -1) {        modalDom.parentNode.parentNode.parentNode.appendChild(modalDom)      }  else {        isNested(modalDom.parentNode)      }    }  }}

补充二

想到一种弹窗组件 按照常规写法,调用的时候如果是要在业务组件里 通过 这样调用 而不是通过 this.$messagebox('')这样调用 会产生的问题

这种情况是 当我们有如下页面

我是聊天左侧
我是聊天右侧
我是弹窗,无论给我设置多高的zindex 我都不会盖住左侧聊天框

转载于:https://www.cnblogs.com/WhiteHorseIsNotHorse/p/9825521.html

你可能感兴趣的文章
Java 编码 UTF-8
查看>>
SpringMVC实战(注解)
查看>>
关于静态属性和静态函数
查看>>
进程的基本属性:进程ID、父进程ID、进程组ID、会话和控制终端
查看>>
spring+jotm+ibatis+mysql实现JTA分布式事务
查看>>
MyBatis启动:MapperStatement创建
查看>>
调查问卷相关
查看>>
eclipse启动无响应,老是加载不了revert resources,或停留在Loading workbench状态
查看>>
1. Git-2.12.0-64-bit .exe下载
查看>>
怎样关闭“粘滞键”?
查看>>
[转]React 教程
查看>>
拓扑排序介绍
查看>>
eclipse打开工作空间(workspace)没有任务反应
查看>>
使用Sybmol模块来构建神经网络
查看>>
字符串去分割符号
查看>>
WPF中,多key值绑定问题,一个key绑定一个界面上的对象
查看>>
UML类图简明教程
查看>>
java反编译工具(Java Decompiler)
查看>>
Android开发之自定义对话框
查看>>
微信Access Token 缓存方法
查看>>