xj.focus 区分聚焦模式

基本介绍

简介 : 这个插件主要用于判断标签的聚焦方式,如果聚焦是由鼠标或触屏的点击导致的,被聚焦的标签会被添加 xj-focus-ontap 的类名,如果聚焦是由于按了键盘的 Tab 键导致的,被聚焦的标签会被添加 xj-focus-ontab 的类名,你可以简单的将这个插件当作是 :focus-visible 伪类的 Polyfill 方案,用它来区分设置不同聚焦方式下的 outline 外边框,为用户提供更好的样式和交互体验。

兼容 : IE10+ / Edge12+ / Firefox / Chrome / Safari / Opera / IOS Webkit / Android Platform

更新 : https://github.com/xjZone/xj.focus/blob/master/upgrade.md

源码 : https://github.com/xjZone/xj.focus/

协议 : Apache License 2.0

版本 :


引入插件

首先是引入相关的文件,推荐使用带 immutableJSDelivr CDN:


常规标签

在引入插件之后,那些可被聚焦的元素,如果是通过点击导致的聚焦,就不会显示出外边框,如果是通过键盘的 Tab 键导致的聚焦,就会显示出外边框,但允许用户输入的那些可编辑的元素如 input[type="text"]textarea 是例外,它们被聚焦的时候总会显示出外边框,这和 :focus-visible 伪类的表现是相同的,但这种特例你也可以通过 # 配置列表 里的 ontabSelector 参数进行修改。


媒体标签

根据 whatwg 描述,audiovideo 标签的点击事件和键盘事件都不会传递到上层,也就是无法冒泡或捕获,这导致我们无法根据用户的操作方式来判断聚焦的形式,插件采取的做法是将它们的聚焦都当作由点击导致,所以不显示外边框,再用 :focus-visible 这个伪类选择器进行补充设置,如果你想了解更多相关信息或者希望改变这个设置,可以查看 # 配置列表 里的 ontapSelector 参数。


异形标签

两个特殊的标签 svg amap area,由于它们可能呈现不规则形状,所以如果对它们的设置 outlinebox-shdoaw 样式,在 IE 和 Firefox 中可能不会生效,且可能导致浏览器原本自带的聚焦样式失效,考虑到兼容,所以插件没对它们设置聚焦样式,聚焦后的样式会保持浏览器的默认状态,如果你不需要兼容 IE 或 Firefox,可以通过 # 配置列表 里的 otherSelector 参数进行控制。


参数设置

插件提供了一些参数,用于定义聚焦的各种细节,而这些参数都可通过使用目标容器上的 xj-focus="{}" 这个内联属性来完成设置,下面是一个简单的例子,使用 ontabAlways 参数可让聚焦总被当作是按了 Tab 键导致的,从而显示出外边框,使用 ontapAlways 参数可让聚焦总被当作是通过点击导致的,从而不显示外边框,使用 otherAlways 参数可让插件什么也不做,保持浏览器默认状态。


测试状态

默认的情况下,当节点失焦后插件设置的相关类名就会同时被移除,这是为了避免聚焦状态继续被延续,但立即移除相关类名也导致了我们很难在 DevTool 面板中检查并调试它,所以插件提供了 debug 参数,当这个参数被设为 true 时,类名就不会被自动移除了,正如下面的例子中,第二个 input[type="text"] 由于设置了 debug:true 参数,所以在节点失焦之后插件相关的类名也不会被移除。


边框选择

插件提供了 style 参数,用于控制生成外边框所使用的样式,该参数默认值是 'auto',也就是除 Safari 之外的浏览器,默认都使用 box-shadow 样式来生成外边框,这是因为 box-shadow 能兼容圆角,而 Safari 则默认使用 outline 样式来生成外边框,这是因为 Safari 的表单控件没设置 -webkit-appearance:none;box-shadow 样式就无法生效,下面是使用这些参数的简单案例。


内嵌模式

聚焦元素所在的父节点被设置了 overflow:hidden;,那么聚焦后外边框就可能被裁剪而看不到,此时可使用 inset:true 的设置,来让边框变成内嵌模式,这样就不用担心因为裁剪而看不到的问题了,Firefox 默认的表单控件被设置了background-color:field;,此时 inset 模式的 box-shadow 样式会无效,因此当使用了 style:'auto' 时,Firefox 会自动改用 outline 来生成内边框。


参数继承

内联属性 xj-focus="{}" 不是非得设置在被聚焦的节点上,其实设置在目标节点的上层节点也是可以的,只要 inherit 参数不明文设为 false,那么这个内联属性的设置就可被继承,当目标节点和它的上层节点设置了同个属性时,层级越低的属性权重越高,继承的好处是如果想定义某个区域的边框,无需逐个设置,只需要设置父容器然后继承就行,下例展示了通过继承设置不同的 inset 参数。


针对 Firefox 的设置

下面的两段样式都是属于可选的,前者用于去掉 Firefox 聚焦后显示的多余边框,后者用于避免 Firefox(MacOS) 在聚焦后边框样式变成 ThreeDLightShadow 导致边框和外边框混在一起的问题,实际上不少框架如 Bootstrap 或 ElementUI 等都会帮我们完成这些样式重置的工作,所以实际上你也未必需要用到它们,尤其是第二段代码,如果你已经定义过这些表单控件的边框,那就不需要再设置了。


自定义边框的样式

xj.focus 主要用于区分 focus 事件的触发模式,至于说插件所提供的 xj.focus.css 样式文件,其实未必合适你的项目,毕竟不同项目的主色调都不一样,好在这个文件也不复杂,你可以选择忽略这个文件,然后自己重新定义一些更合适你的项目的样式规则,下面的代码就是 xj.focus.css 文件的所有内容了,如果不喜欢这个 #3399ffrgba(51,153,255,0.750); 蓝色,就自定义其他的颜色吧。


xj.focus 对象

全局中的 xj.focus 对象上存放着一些属性和方法,version 属性会返回当前插件的版本,ontab, ontap, other 这三个属性可用于判断当前聚焦的类型,ontabSet(), ontapSet(), otherSet() 这三个方法则是可让节点进入对应的 focus 状态,并不是说真的会有聚焦操作的表现,只是节点上会出现对应的类名而已,下面是一个例子,你得审查元素,才能在点击按钮后看到对应的结果。


配置列表

以下 Demo 罗列了本插件所有可用的配置,并且展示了插件进行全局配置的具体操作方法,需要注意的是,全局配置得在引入插件之前就设置好,否则插件加载并执行的时候找不到配置,就会认为配置不存在,并且版本号也要对得上,否则插件也是不理会的,例如本页面使用的插件是 0.4.0 的版本,在 xj.focusConfig 对象后面跟着的就是 ['0.4.0'],版本匹配是考虑到插件多版本并存而设计的。


参数列表

以下 Demo 罗列了本插件所有可用的参数,并且展示了插件进行参数预设的具体操作方法,需要注意的是,参数预设得在引入插件之前就设置好,否则插件加载并执行的时候找不到预设,就会认为预设不存在,并且版本号也要对得上,否则插件也是不理会的,例如本页面使用的插件是 0.4.0 的版本,在 xj.focusOption 对象后面跟着的就是 ['0.4.0'],版本匹配是考虑到插件多版本并存而设计的。


项目备注

01. 使用 dispatchEvent() 方法触发的 focus 事件并不会真的在 UI 上实现聚焦,所以之后也不会触发 blur 事件,这就导致如果聚焦是由该方法触发的,那么 xj-focus-other 类名可能会长期存在,直到页面上某个节点真实触发了 blur 事件,才会被去掉。

02. 有疑问或者发现 BUG,可到 GitHub 提 Issue,如果觉得插件写得还行,在 GitHub 中为本项目点个 ★Star 吧,感谢啦 ಠ‿ಠ ❤。


推荐阅读

XJ.Chen - 浅谈 :focus 伪类选择器和聚焦后 outline 边框的设置问题


Copyright © 2015- XJ.Chen All Rights Reserved
More XJ Plugins : https://github.com/xjZone/