源代码地址 - trap-focus

version:element-plus 1.0.1-beta.0

这个指令只在dialog中使用了

import { nextTick } from 'vue'
import { on, off } from '@element-plus/utils/dom'
import { obtainAllFocusableElements, EVENT_CODE } from '@element-plus/utils/aria'import type { ObjectDirective } from 'vue'export const FOCUSABLE_CHILDREN = '_trap-focus-children'
export const TRAP_FOCUS_HANDLER = '_trap-focus-handler'export interface ITrapFocusElement extends HTMLElement {[FOCUSABLE_CHILDREN]: HTMLElement[][TRAP_FOCUS_HANDLER]: (e: KeyboardEvent) => void
}// 中文文档示例 https://www.vue3js.cn/docs/zh/guide/custom-directive.html#%E9%92%A9%E5%AD%90%E5%87%BD%E6%95%B0
// api https://www.vue3js.cn/docs/zh/api/application-api.html#directive
// 现在可以直接调用生命周期函数
const TrapFocus: ObjectDirective = {beforeMount(el: ITrapFocusElement) {// obtainAllFocusableElements 是一个过滤el下FOCUSABLE_ELEMENT_SELECTORS所有可以focus和可见的函数// const FOCUSABLE_ELEMENT_SELECTORS =`a[href],button:not([disabled]),button:not([hidden]),:not([tabindex="-1"]),input:not([disabled]),input:not([type="hidden"]),select:not([disabled]),textarea:not([disabled])`el[FOCUSABLE_CHILDREN] = obtainAllFocusableElements(el)el[TRAP_FOCUS_HANDLER] = (e: KeyboardEvent) => {const focusableElement = el[FOCUSABLE_CHILDREN]// 如果el[FOCUSABLE_CHILDREN]中含有子元素 并且键盘按下的是`Tab`if (focusableElement.length > 0 && e.code === EVENT_CODE.tab) {// 如果只有一个元素if (focusableElement.length === 1) {// 阻止默认行为就是tab无效e.preventDefault()// 如果当前获得焦点的元素不是这唯一一个元素 那么让他获得焦点if (document.activeElement  !== focusableElement[0]) {focusableElement[0].focus()}return}const goingBackward = e.shiftKeyconst isFirst = e.target === focusableElement[0]const isLast = e.target === focusableElement[focusableElement.length - 1]// shift + tab 同事按下 并且是第一个元素的话// 个人理解就是 tab 反方向if (isFirst && goingBackward) {e.preventDefault()// 最后一个focusfocusableElement[focusableElement.length - 1].focus()}// 没有shift 如果到了最后一个 则第一个focusif (isLast && !goingBackward) {e.preventDefault()focusableElement[0].focus()}// the is critical since jsdom did not implement user actions, you can only mock it// DELETE ME: when testing env switches to puppeteerif (process.env.NODE_ENV === 'test') {const index = focusableElement.findIndex(element => element === e.target)if (index !== -1) {focusableElement[goingBackward ? index - 1 : index + 1]?.focus()}}}}on(document, 'keydown', el[TRAP_FOCUS_HANDLER])},updated(el: ITrapFocusElement) {nextTick(() => {// 重新获取el[FOCUSABLE_CHILDREN] = obtainAllFocusableElements(el)})},unmounted(el: ITrapFocusElement) {off(document, 'keydown', el[TRAP_FOCUS_HANDLER])},
}export default TrapFocus

element-ui element-plus trap-focus - 分析相关推荐

  1. Element UI table组件源码分析

    本文章从如下图所示的最基本的table入手,分析table组件源代码.本人已经对table组件原来的源码进行削减,源码点击这里下载.本文只对重要的代码片段进行讲解,推荐下载代码把项目运行起来,跟着文章 ...

  2. Element UI Element Plus之改变表格单元格颜色

    首先官网文档中有 Table 表格 组件的属性说明,只需要在el-table标签中加上:cell-style="xxx",以及实现该方法即可.Element UI框架和Elemen ...

  3. Vue + Bootstrap|Element UI——模态框被遮罩层遮盖问题解决方案

    问题描述 问题分析 1)若dialog弹出框,它的遮罩层就会被插入到body标签下(即与组件所在的最外层div同一层级) Element UI中设置了modal-append-to-body='tru ...

  4. 网站快速成型工具-Element UI

    Element UI Element UI 1 什么是Element UI???? 2 搭建环境 2.1 创建vue项目 2.2 安装 element-ui组件 2.3 Element UI 引入 3 ...

  5. element UI的带输入建议el-autocomplete总结(详细,全)

    Table of Contents 引用el-autocomplete 触发带输入建议的两种方式 转成输入建议回调的数据结构 增加回车触发事件 解决回车后建议输入框没消失的bug vue+elemen ...

  6. vue组件库介绍以及组件库Element UI 的使用

    组件库 前言 这篇文章介绍vue组件库! 介绍什么是组件库以及Element UI组件库的使用! 看完不会你打我.哈哈哈,开玩笑的,不多说,上刺刀!! 1. 什么是 vue 组件库 在实际开发中,前端 ...

  7. Vue UI组件库(Element UI库)

    1 移动端常用 UI 组件库 1. Vant Vant 4 - 轻量.可定制的移动端组件库 (vant-ui.github.io)  2. Cube UI cube-ui Document (didi ...

  8. Vue + Element UI|可随商品单价和数量实时更新总价的表格

    引入Element UI可参考文章 如何在Vue项目引入Element UI Element UI官网 效果 编辑表格中的单价和采购数量,总金额.商品总价.合计金额可以同步变化.点击测试按钮在控制台打 ...

  9. 【Element UI】日期选择器el-date-picker 默认选中当前日期==> 不可选当日之前的日期

    一个人能否合理表达自己的攻击性是健康与否的重要标准. 参考Element UI  Element - The world's most popular Vue UI framework 目录 1.默认 ...

  10. Element UI 组件库分析和二次开发(一)

    我的本地开发环境:M1 芯片Mac,node v12.22.10. 一.Element UI 组件库二次开发的大致流程 1. 从 Element 官方 clone 一份 dev 源码到本地 2. 安装 ...

最新文章

  1. 技术有时间衰减因子.
  2. 分享3一个博客HTML5模板
  3. python中ipo模型有_python ipo模型是指什么?_后端开发
  4. React开发(150):注意定义数组格式
  5. 刚刚!北京高考时间和开学时间定了
  6. 树莓派网页服务器的网页留言板,树莓派利用Django搭建聊天网页服务器 —— 准备篇...
  7. run、kill、return、stoprobot、stop
  8. Spring Boot学习总结(24)——Spring Boot 2.5 新特性一览
  9. MySQL__数据处理之查询
  10. docker 厂商 容器_我终于不用再解释Docker了!
  11. 41. Understand implicit interfaces and compile-time polymorphism
  12. 国内首个SENT 信号解析软件 适配NXP KMA321, melexis MLX90372等SENT信号输出芯片 完美替代PicoScope 解析SENT
  13. Aria2 下载工具(转)
  14. 论文解析[10] Contextual Transformer Networks for Visual Recognition
  15. ionic 以及cordova apk打包成功,安装不成功,显示Failure [INSTALL_FAILED_CONFLICTING_PROVIDER]
  16. (2021牛客多校一)A.Alice and Bob(博弈)
  17. 手机vr玩电脑上的3d游戏以及看视频
  18. js中使用new操作符做了什么事情
  19. 不同进制之间的转换的各种方法
  20. EXFO 光时反射仪MAX-730C-SM1基本规格

热门文章

  1. 草图大师SketchUp绘图-定制亚克力外壳教程
  2. 淘宝商品详情页视频接口(视频参数,sku属性参数,销量参数等页面上的数据均可以采集,支持高并发请求)
  3. 2021广工计算机考研,2021计算机考研大纲大纲什么时候公布
  4. 英文写作中注意的问题——想到哪里记哪里
  5. mysql多表查询临时表_MySQL 之多表查询
  6. 介绍一个优质的学习分类网站-学吧导航
  7. 基于macd、kdj、ma技术指标分析股票多空方向——应用开发6 导出到EXCEL表格
  8. 茶学领域如何用的上计算机,计算机视觉图像处理技术在茶学领域应用分析
  9. ANOMALY: meaningless REX prefix used
  10. 经典游戏服务器端架构概述