Skip to content

Latest commit

 

History

History
34 lines (20 loc) · 2.72 KB

HOW-IT-WORKS.md

File metadata and controls

34 lines (20 loc) · 2.72 KB

原理

对于一次调用,主要分为三个部分,分别是“入口”、“列表”和“出口”。每一个部分都会注册一些监听事件,最终被组合关联在一起,调用 .focus(),完成“让焦点从入口进入,在列表移动,从出口退出”的任务。

例如,进行一个包含入口、列表和出口的最简单的调用:

focusFly(["#b1", "#b3"], {
  onEscape: true,
  entry: "#b0",
  exit: "#b3",
});

上面的调用里,入口是元素“#b0”,出口是元素“#b3”,列表是一个范围,这个范围的头元素是“#b1”,尾元素是“#b3”。在调用 focusFly 的时候,实际上注册了一些事件:

  • 入口,元素 #b0 注册点击(click)事件;
  • 列表,元素 #b1 和 #b3 共同的父元素,注册 clickfocusinfocusoutkeydownmousedown 事件;
  • 出口,重复利用列表的 clickfocusout 事件。

下面解释每种事件的具体作用,部分内容会结合上面的代码块。

入口的点击事件:触发点击事件后,会对列表的第一个元素调用 .focus(),结合上面代码块的列表,则是 b1.focus()

列表的 keydown 事件:事件会监听键盘按下的按键,让焦点在列表中循环,在上面的代码块里,事件会检查两个元素,分别是列表的头和尾,检测到当前元素是 #b3,并且同时按下了 Tab,将会执行 b1.focus();检测到当前元素是 #b1,并且同时按下了 Shift-Tab,将会执行 b3.focus()

列表的 mousedownfocusin 事件:这两个事件主要作用是焦点矫正,考虑一个场景,有一个列表包含 #b1、#b2、#b3 三个元素,点击元素 #b2 后,焦点聚焦 #b2,这时点击 #b3 之后的空白区域,#b2 会失焦,然后按下 Shift-Tab,由于焦点矫正的功能,焦点回到了 #b2,而不是空白区域的上一个元素 #b3。

出口的 focusout 事件:虽然该事件被注册在列表上,但它的作用是出口,让焦点回到入口,考虑一个场景,一个背景是灰色蒙层的弹窗,弹窗的内部元素是列表,要求点击灰色蒙层的时候,焦点回到“打开”按钮,点击蒙层后,focusout 中会执行延迟 0s 的定时器,在其中调用 document.activeElement 来获取当前聚焦元素,如果该元素不属于列表,则通过 .focus() 让焦点回到入口的“打开”按钮。

出口的 click 事件:该事件被注册在列表上,但作用是出口,让焦点回到入口,该事件会检测被点击的元素是否是出口元素,如果是,将对入口调用 .focus(),结合上面的代码块,点击 #b3 之后,将调用 b0.focus()