龙空技术网

Vuejs通过浏览器导航关闭模态框,实现增强的用户体验

前端梁哥 169

前言:

眼前大家对“js弹出模态窗口”大约比较看重,你们都需要了解一些“js弹出模态窗口”的相关资讯。那么小编在网上网罗了一些对于“js弹出模态窗口””的相关资讯,希望看官们能喜欢,姐妹们快快来了解一下吧!

在Vuejs项目中,我们想实现这样一个功能,当有模态框处于显示状态,按下浏览器的后退按钮或者后退快捷键,不离开当前页面,而是关闭最顶层的模态框,这是增强用户体验的一种设计,那么该如何实现呢?

在这里,我们以Vue3中的element-plus UI库讲解,众所周知,常用的模态框有3种,分别是:自定义对话框,消息提示框,抽屉;我们的实现原理是,当路由导航之前,查找页面中的模态框DOM元素,调用关闭按钮的单击方法来关闭模态框;原理是不是很简单?

接下来,我们看代码实现。首先,我们创建一个模块文件modal.js,文件名大家可以随便起。

然后,我们定义getAllModals函数,通过审查元素,我们得知对话框和抽屉的容器元素都有el-overlay类,我们就通过这个类进行查找,删选出可见的模态框容器元素。数组的构造函数方法from用于将迭代器或类数组对象转化为真正的数组。

/** @returns {HTMLDivElement[]} 所有可见的模态框容器元素 */const getAllModals = () => {  return Array.from(document.body.querySelectorAll('.el-overlay'))    .filter(_ => window.getComputedStyle(_, null).display !== 'none')}

接下来,我们定义closeModal函数,用于关闭模态框,返回true,表示成功关闭了一个模态框。后面,我们会使用这个返回值来决定导航的逻辑。

/** @param {HTMLDivElement} el */const closeModal = el => {  if (el) {    /** @type {HTMLButtonElement} */    const btnClose = el.querySelector('.el-dialog__close, .el-drawer__close')    if (btnClose) {      btnClose.click()      return true    }  }}

接下来,我们定义closeTopModal函数,用于关闭处于顶层的模态框,我们通过zIndex判断模态框的层叠次序。

export const closeTopModal = () => {  return closeModal(    getAllModals()      .reduce((t, _) => t ? +t.style.zIndex > +_.style.zIndex ? t : _ : _, null)  )}

接下来,我们定义closeAllModals函数,用于关闭所有模态框,用户登录状态发生变化的时候会用到。

export const closeAllModals = () => getAllModals().forEach(closeModal)

接下来,我们定义closeMsgBox函数,用于关闭消息提示框,返回true,表示成功关闭了一个消息提示框。后面,我们会使用这个返回值来决定导航的逻辑。

export const closeMsgBox = () => {  const el = document.body.querySelector('.el-overlay.is-message-box')  if (el) {    const visible = window.getComputedStyle(el, null).display !== 'none'    if (visible) {      /** @type {HTMLButtonElement} */      const btnClose = el.querySelector('.el-message-box__headerbtn')      if (btnClose) {        btnClose.click()        return true      }    }  }}

该模块文件的最后,我们定义closeMsgBoxAndModalAll函数,用于关闭所有打开的消息提示框和模态框。

export const closeMsgBoxAndModalAll = () => {  closeMsgBox()  closeAllModals()}

现在,我们可以转向路由模块文件了,我们对router的beforeEach导航守卫进行拦截,如果成功关闭了一个任意类型的模态框,那么阻止页面跳转。

router.beforeEach((to, from, next) => { if (closeMsgBox() || closeTopModal()) {    return next(false)  }  next()})

实现起来就是这么简单,不是吗?我以后有时间会分享更多的Web开发技术内容,欢迎大家阅读,学习!若大家有更好的解决方案,也欢迎分享出来,共同进步,谢谢!

标签: #js弹出模态窗口