Bootstrap

Vue2、Element中实现Enter模拟Tab,实现切换下一个框的效果

目录

📃前序        

👉开发历程

💻实际代码

📽实现效果图


前序        

        在几乎所有的浏览器中,都具备通过 Tab 键来切换焦点的功能。然而,有些用户提出了强烈要求,希望能够增加通过 Enter 键切换焦点的功能。究其根本,无非是为了习惯性操作而使系统作出要求,秉持着甲方优先的态度,故实现此需求。

开发历程

        表单中拥有多种类型的输入框包括文字、时间、选择、富文本等,仅实际测试,由于下拉框中已经将enter键入的操作固化为选择某一选项的自有功能,又考虑表单中文字输入框较多,故采用此最优解:将通过捕获全局的 keydown 事件,并在检测到 Enter 键按下时,模拟 Tab 键的行为。同时,我们还需要确保只有在当前聚焦的元素是输入框时才进行这种模拟,以避免影响选择框和其他非输入类型的控件。

keyCode表:

实际代码

解释:

  1. 全局事件监听:我们在 mounted 钩子中为窗口添加了一个全局的 keydown 事件监听器,该监听器检查当前是否有输入框处于聚焦状态,并处理 Enter 键和 Tab 键的事件。
  2. 防止默认行为:在检测到 Enter 键或 Tab 键按下时,我们调用 event.preventDefault() 来阻止默认行为。
  3. 切换焦点:通过获取当前聚焦的输入框在所有输入框中的索引,计算出下一个应该聚焦的输入框,并将其设置为当前聚焦元素。
  4. 销毁监听器:在组件销毁之前移除事件监听器,以避免内存泄漏。
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Enter to Tab Example with Select Box</title>
    <!-- 引入 Element UI CSS -->
    <link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css">
</head>
<body>
<div id="app">
    <el-form label-position="left" label-width="80px" style="width: 300px;">
        <el-form-item label="Name">
            <input type="text" v-model="form.name">
        </el-form-item>
        <el-form-item label="Email">
            <input type="text" v-model="form.email">
        </el-form-item>
        <el-form-item label="Phone">
            <input type="text" v-model="form.phone">
        </el-form-item>
        <el-form-item label="Country">
            <el-select v-model="form.country" placeholder="Select Country">
                <el-option
                    v-for="country in countries"
                    :key="country.value"
                    :label="country.label"
                    :value="country.value">
                </el-option>
            </el-select>
        </el-form-item>
        <el-form-item>
            <button @click="submitForm">Submit</button>
        </el-form-item>
    </el-form>
</div>

<script src="https://cdn.jsdelivr.net/npm/vue@2"></script>
<script src="https://unpkg.com/element-ui/lib/index.js"></script>
<script>
    new Vue({
        el: '#app',
        data() {
            return {
                form: {
                    name: '',
                    email: '',
                    phone: '',
                    country: ''
                },
                countries: [
                    { value: 'China', label: 'China' },
                    { value: 'USA', label: 'USA' },
                    { value: 'Japan', label: 'Japan' }
                ],
                inputElements: null,
                currentIndex: 0
            };
        },
        mounted() {
            this.inputElements = document.querySelectorAll('input[type="text"]');
            window.addEventListener('keydown', this.handleEnterOrTab);
            this.inputElements[0].focus();
        },
        beforeDestroy() {
            window.removeEventListener('keydown', this.handleEnterOrTab);
        },
        methods: {
            handleEnterOrTab(event) {
                if (event.keyCode === 13 && document.activeElement.tagName.toLowerCase() === 'input') { // keyCode for 'Enter' key is 13
                    event.preventDefault(); // Prevent default action of Enter key
                    const currentIndex = Array.from(this.inputElements).indexOf(document.activeElement);
                    const nextIndex = (currentIndex + 1) % this.inputElements.length;
                    this.inputElements[nextIndex].focus();
                    this.inputElements[nextIndex].select();
                } else if (event.keyCode === 9) { // keyCode for 'Tab' key is 9
                    event.preventDefault(); // Prevent default action of Tab key
                    const currentIndex = Array.from(this.inputElements).indexOf(document.activeElement);
                    const nextIndex = (currentIndex + 1) % this.inputElements.length;
                    this.inputElements[nextIndex].focus();
                    this.inputElements[nextIndex].select();
                }
            },
            submitForm() {
                console.log(this.form);
            }
        }
    });
</script>
</body>
</html>

实现效果图

;