表单聚焦不同于表格,表格里面的元素比较单一,而表单里面的元素比较多样化,常见的有input,button,textarea和upload等等
所以相对于表格来讲表单实现这一功能是更加复杂一点,在CSDN也找到一个类似的,参考了花椒姐的文章,不过花椒姐的需求跟我的不大一样;我这是一个主页面表单,然后点击新增弹出对话框表单,两个表单元素。第一个只有 input 和 button 标签,第二个有input、select、textarea、upload和下面三个button标签,都需要移动聚焦。对我这种白小白来讲,呜呜呜,熬夜加班肝...
先讲讲思路 ,给每个需要选中聚焦的表单元素加一个公共类,然后再加一个@keydown事件。如果事件没用可以换成@keydown.native。 / * tip:为了小火汁焖能更好的看清代码,我把v-model,data和prop其他的属性全删除了,大家开发的时候不能删除哦~ * /
<el-form>
<el-form-item label="编号">
<el-input class="key_focus1" @keydown="keyDown($event, 1, 0)" />
</el-form-item>
<el-form-item label="说明">
<el-input class="key_focus1" @keydown="keyDown($event, 1, 1)" />
</el-form-item>
<el-form-item>
<vxe-button class="key_focus1" @keydown="keyDown($event, 1, 2)">搜索</vxe-button>
<vxe-button class="key_focus1" @keydown="keyDown($event, 1, 3)">重置</vxe-button>
</el-form-item>
</el-form>
<el-dialog>
<el-form>
<el-form-item label="编号">
<el-input class="key_focus2" @keydown="keyDown($event, 2, 0)"></el-input>
</el-form-item>
<el-form-item label="类型"">
<el-tree-select class="key_focus2" @keydown="keyDown($event, 2, 1)"/>
</el-form-item>
<el-form-item label="说明">
<el-input class="key_focus2" @keydown="keyDown($event, 2, 2)"></el-input>
</el-form-item>
<el-form-item label="图片">
<image-upload class="key_focus2" @keydown="keyDown($event, 2, 3)">
</image-upload>
</el-form-item>
</el-form>
<template #footer>
<span>
<el-button class="key_focus2" @keydown="keyDown($event, 2, 4)">保存</el-button>
<el-button class="key_focus2" @keydown="keyDown($event, 2, 5)">重置</el-button>
<el-button class="key_focus2" @keydown="keyDown($event, 2, 6)">关闭</el-button>
</span>
</template>
</el-dialog>
实现过程:有了公共类 key_focus 后,就可以通过 document.querySelectorAll 原生方法去获取含有公共类的 dom 节点,并返回一个节点数组,然后点击加了公共类的元素并触发事件,获取参数 index,最后再给节点数组 [index] 加上focus就能聚焦成功
js代码:可直接复制使用(๑´ڡ`๑) (๑¯ิε ¯ิ๑) (๑•́ ₃ •̀๑) ( ∙̆ .̯ ∙̆ ) (๑˘ ˘๑) (●′ω`●) ︶ε╰✿ ✿◡‿◡ (●・̆⍛・̆●)
function keyDown (e, sort, index) {
if (!(e.keyCode === 37 || e.keyCode === 38 || e.keyCode === 39 || e.keyCode === 40))
return
let key_focusAll = document.querySelectorAll(`.key_focus${sort}`) //获取公共类名的数组
let midIndex = Math.floor((key_focusAll.length - 1) / 2) // 取中间值的索引
// 方向左键 37
if (e.keyCode === 37) {
if (index === 0) return; index--
}
// 方向右键 39
else if (e.keyCode === 39) {
if (index < key_focusAll.length - 1) index++
}
// 方向上键 38
else if (e.keyCode === 38) {
while (index - midIndex < 0) { midIndex-- }
index -= midIndex
}
// 方向下键 40
else if (e.keyCode === 40) {
while (index + midIndex > key_focusAll.length - 1) { midIndex-- }
index += midIndex
}
if (sort === 1) { // 页面表单,适用于只有button和input的表单
let isButton = key_focusAll[index].toString().indexOf('Button') !== -1
isButton ? key_focusAll[index].focus() : key_focusAll[index].querySelector('input').focus()
}
else if (sort === 2) { // 对话表单,适用于复杂类型的表单
// 上传按钮(需要在input上面,因为文件上传为input="file")
if (key_focusAll[index].querySelector('.el-upload')) {
key_focusAll[index].querySelector('.el-upload').focus(); return
}
// 输入框 包含 input select
if (key_focusAll[index].querySelector('input')) {
key_focusAll[index].querySelector('input').focus(); return
}
// 文本域
if (key_focusAll[index].querySelector('textarea')) {
key_focusAll[index].querySelector('textarea').focus(); return
}
// 按钮 (按钮元素不被生成额外标签所包裹)
if (key_focusAll[index].toString().indexOf('Button') !== -1) {
key_focusAll[index].focus(); return
}
}
}
热呼呼的知识:即使你直接给 input 标签加类,element 依然会自动生成一个div 标签进行包裹,这样子你加的公共类就在那个包裹标签上了,你就需要在包裹标签上用querySelector('input') 找到的 input标签。 button 标签不会被生成包裹标签,其他大部分表单标签都会
而对于上下键,我实在不知道咋整比较好,因为表单不像表格一样这么规整,所以我就给上下键赋值一个比较大的数,让上下键比左右键跳得更远(反正我是不会承认我菜)