所谓隐藏细节,指的是文档中并未体现,需要查看源码才知晓的细节知识,在组件的高阶应用中,这些细节可以帮助开发者更好的进行开发。
键盘快捷键
如果大家单独引入某一个 UI 组件库,建议同时引用 Keyboard.css 和 Keyboard.js,对组件的键盘访问做了非常完善的支持。
<link rel="stylesheet" href="https://unpkg.com/lu2/theme/edge/css/common/ui/Keyboard.css">
<script href="https://unpkg.com/lu2/theme/edge/js/common/ui/Keyboard.js"></script>
如果大家引入的是 ui.css 和 all.js,则无需上面的处理,因为默认包含在内了。
Keyboard.js 对常用的 Tab/Shift+Tab、Esc、Enter 等键盘操作进行了处理,包括:
- 合理的索引顺序变化,例如弹框显示的时候,索引焦点会聚焦到弹框上,弹框关闭后,焦点位置还原;
- 所有带有浮层性质的 UI 组件可以使用 Esc 进行隐藏处理;
- 优化了按钮、链接点击和聚焦不同行为下的样式处理;
以上是大家可能知道的,下面讲讲其他隐藏的细节知识。
判断某行为是否键盘触发
鼠标点击按钮可以显示下拉,键盘聚焦按钮回车也可以显示下拉,此时,交互场景不同,列表显示的 UI 也应该有所不同,在键盘交互场景下,应该高亮控件元素。
在 CSS 中,类似的样式处理可以交给 :focus-visible
伪类,不过这个伪类兼容性目前还不够,需要使用 JS 进行判断处理,Keyboard.js 暴露了一个全局属性 isKeyEvent
,可以判断当前语句的执行是否与键盘行为相关,例如:
if (window.isKeyEvent) { // 键盘操作触发 } else { // 点击操作触发 }
accesskey属性的支持
引入 Keyboard.js 后,用来自定义快捷键的 accesskey
属性得到了更好的支持。
例如有如下 HTML:
<form id="f0" is-validate> <input type="search" class="ui-input" accesskey="/" required> <button type="submit" class="ui-button" data-type="primary" accesskey="s">搜索</button> </form>
搜索框这里设置了 accesskey="/"
,此时大家只要按下键盘的 /
键,搜索框就会被聚焦;搜索按钮设置了 accesskey="s"
,此时大家只要按下 S
键,搜索按钮就会聚焦,而按下 Alt + S
(Mac 下是 Control + Option + S
)键,就会触发搜索表单提交(通过触发提交按钮的点击行为触发)。
下面就是对应的测试表单,大家可以按下 /
键、 S
键或组合键试一试。
另外,按下 shift + ?
会出现页面中所有 accesskey
快捷键内容的提示。
隐匿的公开方法
部分 UI 组件其实以公开或半公开的方式暴露了一些与 UI 样式无关的 JavaScript 方法,当大家引入对应的 UI 组件后,这些方法是可以直接拿来使用的,包括下面这些。
Color 颜色选择
Color 颜色选择组件暴露了几个颜色转换相关的静态方法。
方法名 | 说明 | 参数和返回值 |
---|---|---|
Color.funHslToHex(h, s, l, a) | 任意的 hsl(a) 色值转换成 #rrggbb(aa) 格式的色值。例如:Color.funHslToHex(1/3, 0.5, 0.5, .6)
// 返回值是 "40bf4099" |
h, s, l, a这4个参数范围均是0-1。 |
Color.funHexToHsl(hex) | hex 色值表示转 hsl() 函数表示。例如:Color.funHexToHsl('#468be0') // 返回值是 [0.592, 0.712963, 0.57647] Color.funHexToHsl('468b'); // 返回值是 [0.5833, 0.3333, 0.4, 0.7333] |
参数 hex 类型为字符串,必需,返回值是数组,数组项的数值范围均是0-1。 |
Color.funRgbToHex(rgb) | rgb() 函数色值转 hex 色值。例如:Color.funRgbToHex('rgb(50, 255, 50)') // 返回值是 "#32ff32" Color.funRgbToHex('rgba(128, 10, 10, .75)') // 返回值是 "#800a0abf" |
参数 rgb 类型为字符串,必需。 |
Datetime 时间选择
Datetime 时间选择组件在字符串、日期对象上扩展了几个 Nottifill 性质的方法。
扩展名称 | 说明 | 参数和返回值 |
---|---|---|
String.prototype.toTime() | 时间字符串转换成格式符合的时分秒数组。例如:'12:3:9'.toTime()
// 返回值是 ["12", "03", "09"] |
返回值是数组,会自动补零。 |
String.prototype.toDate() | 将字符串日期格式转换成日期对象。例如:'2019-03-23'.toDate() // 返回值等同于 new Date(2019, 2, 23) '2022年8月9日'.toDate() // 返回值等同于 new Date(2022, 7, 9) |
返回是是 Date 对象数据类型。 |
Date.prototype.toArray() | 将日期对象转换成包含年月日信息的数组。例如:new Date(2022, 8, 9).toArray()
// 返回值是 [2022, "09", "09"] |
返回值是数组,如果月份和日期不足 10,会自动补零。 |
Datalist 数据列表
Datalist 数据列表也暴露了若干静态方法,主要是字符的转义和反转义处理。
方法名 | 说明 | 参数和返回值 |
---|---|---|
Datalist.stripHTML(str) | 过滤 HTML 标签字符串。例如:Datalist.stripHTML('<script>alert(1)</script>')
// 返回值是 "alert(1)" |
返回值是过滤后的字符串。 |
Datalist.encodeHTML(str) | 转义 HTML 标签字符串。例如:Datalist.encodeHTML('<script>')
// 返回值是 "<script>" |
返回值是转义后的字符串。 |
Datalist.decodeHTML(str) | 反转义 HTML 标签字符串。例如:Datalist.decodeHTML('<script>')
// 返回值是 "<script>" |
返回值是反转义后的字符串。 |
Table 列表解决方案
Table 列表解决方案内置了一个基于 ES6 模板字符串原生能力的模板解析方法 interpolate。
扩展名称 | 说明 | 参数和返回值 |
---|---|---|
String.prototype.interpolate(params) | 可以使用 ES6 模板字符串进行模板解析。例如已知模板元素:<template id="tpl"> <ol>${data.map((value, index) => { return `<li>${value}-${index}</li>` }).join('')}</ol> </template> 此时就可以使用 interpolate 方法对上述 HTML 模板字符串进行解析渲染。 tpl.innerHTML.interpolate({
data: ['L', 'U', 'I']
})
// 返回值是 "<ol><li>L-0</li><li>U-1</li><li>I-2</li></ol>" |
返回值是渲染后的字符串数据。 |
其他
1. 底层定位方法
LuLu UI 组件中所有的浮层定位的底层调用都是一样的,全部都是使用的 Follow.js 中的 DOM 扩展方法。
有时候,处于业务需要,我们需要手动进行定位交互,此时,就可以使用 Follow.js 提供的定位方法。
例如有如下 HTML 结构:
<button id="b0" type="primary" is="ui-button" is-follow="img0">多次点击我</button> <img id="img0" src="logo.svg" hidden>
希望点击按钮的时候图片切换显示,就可以使用下面的代码:
b0.addEventListener('click', function () {
if (img0.clientWidth == 0) {
img0.style.display = 'block';
// 相对按钮定位
this.follow({
offsets: {
x: 0,
y: 10
}
});
} else {
img0.style.display = 'none';
}
});
实时效果:
2. 层级设置
基本上,所有的弹框和浮层都内置了层级顶层设置方法,方法名都是一样的,是 element.zIndex()
。
如果是弹框元素,则执行下面的代码可以让弹框元素层级最高:
dialog.zIndex();
如果是 Drop 下拉元素,则代码为:
drop.element.target.zIndex();
所有组件默认会执行层级最高方法,因此,大多数场景下,大家并不需要知道上面的细节,只有某些特殊场景,需要手动设置位于下层的元素到顶层,就需要用到这里的 zIndex()
方法。
3. 输入增强
在表单验证中,所有的输入框(包括多行输入框)都内置了粘贴和拖移的增强处理,例如去前后空格,手机或邮箱格式化等,但这在 React 下可能会有粘贴不触发 Input 事件的问题,此时,可以设置 data-enhance="false"
关闭此增强处理。
<textarea class="ui-textarea" data-enhance="false"></textarea>
本页贡献者:
zhangxinxu