网站首页 > 基础教程 正文
在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开发技术内容,欢迎大家阅读,学习!若大家有更好的解决方案,也欢迎分享出来,共同进步,谢谢!
猜你喜欢
- 2024-10-29 将vue代码改写成react vue文件如何编译成html
- 2024-10-29 CKEditor 4.14:支持复制粘贴 LibreOffice 文档的富文本编辑器
- 2024-10-29 jQuery UI 小部件(Widget)方法调用
- 2024-10-29 HTML5新增元素介绍及运用 html5新增的功能元素
- 2024-10-29 HTML 打印问题汇总 html怎么打印
- 2024-10-29 HTML 语法的变化,HTML5有哪些新的元素和属性
- 2024-10-29 Element Plus 的 Dialog 组件实现点击遮罩层不关闭对话框
- 2024-10-29 WebView与JavaScript的交互 webview与js交互原理
- 2024-10-29 1-html基本知识 html的基本内容
- 2024-10-29 海量订单系统微服务开发:订单接口管理后台微服务开发、集成测试
- 最近发表
-
- 掌握SpringBoot-2.3的容器探针:实战篇
- kubernetes基础知识之驱逐节点(k8s驱逐节点后恢复)
- Linux环境中制作网络哨兵Sentinel Docker镜像
- k8s之配置CNI网络(k8s 网络配置)
- docker实战之:镜像更新(docker 镜像升级替换)
- 离线在docker镜像方式部署ragflow0.17.2
- Linux日常小技巧Docker打包(docker打包lnmp)
- 使用dockerfile构建docker镜像(docker通过dockerfile构建镜像命令)
- 「云原生」Containerd ctr,crictl 和 nerdctl 命令介绍与实战操作
- Kylin安装Dify(kylin安装部署)
- 标签列表
-
- jsp (69)
- pythonlist (60)
- gitpush (78)
- gitreset (66)
- python字典 (67)
- dockercp (63)
- gitclone命令 (63)
- dockersave (62)
- pythonif (68)
- pythonifelse (59)
- deletesql (62)
- c++模板 (62)
- c#event (59)
- linuxgzip (68)
- 字符串连接 (73)
- nginx配置文件详解 (61)
- html标签 (69)
- c++初始化列表 (64)
- exec命令 (59)
- mysqlinnodbmyisam区别 (63)
- arraylistadd (66)
- console.table (62)
- mysqldatesub函数 (63)
- window10java环境变量设置 (66)
- c++虚函数和纯虚函数的区别 (66)