最基本的用法
<!-- 在 body 底部引入脚本 -->
<script src="js/keypad.js"></script>
<script>
// 可以在 Keypad 的全局变量上设置 isMobile 来为所有实例提供移动端检测
Keypad.isMobile = /Mobile/.test(navigator.userAgent)
</script>
不需要任何额外的参数就可以将一个初始状态的“键盘”载入到页面中,点击动作栏的按钮操作显示/隐藏。
// 使用 new 操作符得到一个实例
var kypd = new Keypad()
kypd.toggle() // 切换
kypd.show() // 显示
kypd.hide() // 隐藏
绑定 & 监听 input 元素
激活下面的输入框触发键盘。提示: Keypad 不会阻止移动端浏览器对于
input
元素的默认事件而导致行为或者
显示异常(放大输入框、元素漂移),需要避免这种的话建议设置 'readonly',具体参考下一示例。
// 使用 new 操作符得到一个实例
var kypd = new Keypad({
// 需要监听的 input 元素选择器
el: '#listened-input'
})
绑定存值的 input 元素
点击下面的六位数密码框会激活键盘,输入的值则会被存入它下方那个只读属性的 input 中。
var password = document.querySelector('#password')
var items = password.querySelectorAll('i')
var input = document.querySelector('#readonly-input')
var kypd = new Keypad({
// 绑定目标 input 元素
input: input,
// 绑定按键抬起状态
onend: function (key) {
var code = key[2] // 按键命令
var n = input.value.length + 1
// 当前按下的是退格键时
if (code === 'backspace') {
n--
if (n === 0) return kypd.hide()
if (n > items.length) n = items.length - 1
items[n - 1].classList.remove('on')
return false
}
if (n > items.length) {
kypd.hide()
return true
}
if (n === items.length) {
items[n - 1].classList.add('on')
return kypd.hide()
}
items[n - 1].classList.add('on')
}
})
// 点击密码框显示键盘
password.addEventListener('click', ev => kypd.show(), false)
其它的选项
在此页面进行一些选项的演示,可结合浏览器的控制台查看对应的 HTML 结构。
按键名称:
等待……按键值:
等待……按键命令:
等待……主题颜色
控制显示
切换键盘
// 使用回调函数的方式配置选项来实例化 Keypad
var kypd = new Keypad(function (options) {
options.dark = true // 使用深色主题
options.name = 'qwer' // 键盘布局修改为 QWER
options.hide = 'click' // 绑定 body 的 'onclick' 事件,点击键盘区域以外的页面部分隐藏
// 绑定按键按下状态
options.onstart = function (key) {
id('options-print-1').textContent = key[0] // 文本
id('options-print-2').textContent = key[1] // 值
id('options-print-3').textContent = key[2] // 命令
}
// 返回修改后的选项
return options
})
var theme = {
dark: id('theme-color-1'),
light: id('theme-color-2')
}
Object.entries(theme).forEach(function (action) {
var name = action[0]
var target = action[1]
target.addEventListener('click', function (ev) {
ev.stopPropagation()
target.querySelector('input[name]').click()
kypd.dark(name === 'dark')
}, false)
})
var control = {
toggle: id('control-1'),
show: id('control-2'),
hide: id('control-3')
}
Object.entries(control).forEach(function (action) {
var name = action[0]
var target = action[1]
target.addEventListener('click', function (ev) {
ev.stopPropagation()
// 获取当前选择的布局
var layout = document.querySelector('input[name="layout"][checked]').value
kypd[name](layout)
}, false)
})
var layout = {
number: id('layout-1'),
qwer: id('layout-2')
}
Object.entries(layout).forEach(function (action) {
var name = action[0]
var target = action[1]
target.addEventListener('click', function (ev) {
ev.stopPropagation()
target.querySelector('input[name]').click()
// 隐藏上一个布局并显示新的
kypd.hide() || kypd.show(name)
}, false)
})
function id (id) {
return document.querySelector('#' + id)
}
自定义键盘布局
使用一个三维数组来直观地制作一个键盘布局,这里演示一个简易的方向键盘。
var kypd = new Keypad({
name: 'wasd', // 使用新增布局的名字
multiple: false, // 仅渲染当前键盘布局
reducer: {
// 这里使用钩子来简单修改下键盘容器的样式
content: function (target) {
target.style.maxWidth = '240px'
return target
},
// 修改用于占位的按键
key: function (target, key) {
if (key[1] === '') {
target.textContent = ''
target.style.height = '0'
target.style.padding = '0'
}
return target
}
}
}, {
// 新增的键盘布局
wasd: [
[[''], ['↑'], ['']],
[['←'], ['↓'], ['→']]
]
})
自定义插件
一些与业务需求相关性高但并不适合整合进库中的代码可以编写成扩展来动态增强 Keypad 的可用性。
下面的例子实现了一个带输入框的键盘(为避免移动端异常,使用的是 readonly 属性的 input 元素)。
function pluginDemo () {
var style = document.createElement('style')
var css = [
'kypd-flex-toolbar {',
'background-color: #f5f5f5;',
'height: 56px; width: 100%;',
'margin-bottom: 8px;',
'display: flex; align-items: center; justify-content: flex-end;',
'}',
'kypd-flex-toolbar .close {',
'background: white; color: #0077ff; margin: 0 12px; border-radius: 2px;',
'height: 44px; min-width: 64px; font-size: 14px; border: none;',
'display: flex; flex: none; justify-content: center; align-items: center;',
'}',
'kypd-flex-toolbar .input {',
'background-color: white; border-radius: 2px;',
'font-size: 16px; color: #333; text-indent: .5em;',
'height: 44px; width: 100%; border: 0; padding: 0; margin-left: 12px;',
'}'
].join('')
// 在 head 中插入一些样式
style.innerHTML = css
document.head.appendChild(style)
// 以上代码会在注册插件时生效,而返回的这个闭包函数只有在实例化时才会运行
return function () {
// 向键盘布局的父级容器注入一个工具条
this.options.reducer.container = function (target) {
var toolbar = document.createElement(this.prefix('elem', 'toolbar'))
var input = document.createElement('input')
var close = document.createElement('button')
input.type = 'text'
input.placeholder = 'Type Enter Key To Send.'
input.readOnly = true
input.classList.add('input')
this.input = input
close.textContent = 'Close'
close.classList.add('close')
close.addEventListener(this.events.start, function () { this.hide() }.bind(this), false)
toolbar.appendChild(input)
toolbar.appendChild(close)
target.insertBefore(toolbar, target.firstChild)
return target
}
// 在 options 中添加一个额外的 onsend 选项给用户
this.options.reducer.key = function (target, key) {
if (key[2] === 'enter') {
target.addEventListener(this.events.end, ev => {
if (typeof this.options.onsend !== 'function') return true
this.options.onsend.call(key, this.input.value)
}, false)
}
return target
}
}
}
// 第一种方式,全局注册插件,之后所有的实例都可以使用这个插件
// 像示例这种需要在注入前动用 options 用户选项的插件最好使用这种方法
Keypad.plugins = [
pluginDemo()
]
var kypd = new Keypad({
name: 'qwer',
// 使用插件提供的选项接口
onsend: function (content) {
document.querySelector('#plugins-input').value = content
}
})
// 第二种方式,使用 kypd.use() 接口为单一实例注册插件
var kypd = new Keypad({
name: 'qwer',
// 使用插件提供的选项接口
onsend: function (content) {
document.querySelector('#plugins-input').value = content
},
// 实例化完成后不要对页面进行注入
inject: false
})
// 注册插件,第二个可选参数可以提供插件的名称,方便定为错误
kypd.use(pluginDemo(), 'Demo Plugin')
// 在完成插件的注册后再对页面进行注入操作
kypd.inject()