- A+
知其然知其所以然
在前端项目开发中,偶尔会有表单提交的问题:
用户输入表单后,不小心按了回车键,导致提前触发了提交事件?
问题概述
当表单中仅有一个input输入框时,按下回车键就会自动触发提交事件,这是为什么呢?
这里就要提到一个标准:W3C
文中最后一句话已经解释了原因:
当表单中只有一个单行文本输入字段时,用户代理应接受在该字段中按Enter键作为提交表单的请求。
既然知道了这种现象不是bug,而是切实的标准后,那我们如何在项目中避免呢,毕竟不是每个项目都希望用户回车的时候突然就触发了提交事件的。
为了提升用户体验,我将提供几个实用方案!
实用方案
1、原生表单
代码复现
<form> <input type="text" id="myInput"> <button onclick="submitForm()">Submit</button> </form>
上述代码省略了部分提交事件方法,重点突出表单。
解决方案
方案1
在 input 中添加 onkeydown="if(event.keyCode==13){return false;}" 。
通过监听 input 输入框的键盘事件来控制表单进程,keyCode的值为13即按下了回车键,返回false,即为取消提交事件。
<form> <input type="text" id="myInput" onkeydown="if(event.keyCode==13){return false;}"> <button onclick="submitForm()">Submit</button> </form>
方案2
在 form 标签中添加 onsubmit="return false;"。
通过主动对form表单添加提交属性,来控制提交事件,return false即为取消提交。
<form onsubmit="return false;"> <input type="text" id="myInput"> <button type="button" onclick="submitForm()">Submit</button> </form>
注:有的人可能会困惑,为什么自己的添加了一样的代码,没有生效的问题,这里需要注意一点,就是 button 按钮的默认事件。
从MDN查询到,button 在不添加 type 属性时,默认值是 submit。
所以,如果你按照此方案不生效,请检查下 button 是否有 type 属性,或已经写了 submit ,input 回车仍然会自动提交,请将 button 的 type 属性改为其他值。
方案3
如果你想保证 dom 元素上的整洁清爽,也可以通过 js 的方式。
使用JavaScript阻止默认行为。
你可以给 input 元素添加一个 keypress 或 keydown 事件监听器,并在用户按下回车键时阻止默认行为。
document.getElementById('myInput').addEventListener('keypress', function (event) { if (event.key === 'Enter') { event.preventDefault(); } });
2、Vue + ElementPlus
代码复现
<template> <el-form> <el-form-item label="姓名" prop="name"> <el-input v-model="form.name" /> </el-form-item> <el-form-item> <el-button type="primary" @click="submitForm">提交</el-button> </el-form-item> </el-form> </template> <script setup lang="ts"> import { reactive } from 'vue' interface IForm { name: string } const form = reactive<IForm>({ name: '', }) const submitForm = async () => { if (form.name.trim() === '') { alert('姓名不能为空') return } alert('提交成功:' + form.name) } </script>
这里用的是 Vue3,vue2+elementUI 也是一样的效果。方案等同。
解决方案
ElementPlus 文档中已经很贴心了做了提示:ElementPlus-Form
就按照官方给出的方案照做就是:
<el-form @submit.prevent> <el-form-item label="姓名" prop="name"> <el-input v-model="form.name" /> </el-form-item> <el-form-item> <el-button type="primary" @click="submitForm">提交</el-button> </el-form-item> </el-form>
当然,也可以写成 @submit.native 效果是一样的。
3、React + Ant Design
代码复现
import { Form, Input, Button } from 'antd' interface FormValues { username: string } const App = () => { const onFinish = (values: FormValues) => { console.log('Form values:', values) } return ( <Form onFinish={onFinish}> <Form.Item label="Username" name="username"> <Input /> </Form.Item> <Form.Item label={null}> <Button type="primary" htmlType="submit"> Submit </Button> </Form.Item> </Form> ) } export default App
解决方案
通过对 input 添加 onKeyDown 监听键盘按键来阻止回车提交事件。
import React from 'react' import { Form, Input, Button } from 'antd' interface FormValues { username: string } const App = () => { const onFinish = (values: FormValues) => { console.log('Form values:', values) } // 监听 onKeyDown 事件,阻止回车键的默认行为 const handleKeyDown = (e: React.KeyboardEvent<HTMLInputElement>) => { if (e.key === 'Enter') { e.preventDefault() } } return ( <Form onFinish={onFinish}> <Form.Item label="Username" name="username"> {/* onKeyDown 事件绑定到 Input 组件 */} <Input onKeyDown={handleKeyDown} /> </Form.Item> <Form.Item label={null}> <Button type="primary" htmlType="submit"> Submit </Button> </Form.Item> </Form> ) } export default App
上述方案,总结完毕!
如果小伙伴有其他更好用的方案,可以留言分享~