動態

詳情 返回 返回

【3分鐘學會】一招禁用表單中input輸入框回車鍵自動觸發提交事件! - 動態 詳情

知其然知其所以然

在前端項目開發中,偶爾會有表單提交的問題:
用户輸入表單後,不小心按了回車鍵,導致提前觸發了提交事件?

問題概述

當表單中僅有一個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

從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

上述方案,總結完畢!

如果小夥伴有其他更好用的方案,可以留言分享~

user avatar cyzf 頭像 Leesz 頭像 alibabawenyujishu 頭像 haoqidewukong 頭像 zaotalk 頭像 steven_code 頭像 nihaojob 頭像 freeman_tian 頭像 jingdongkeji 頭像 qingzhan 頭像 dirackeeko 頭像 chongdianqishi 頭像
點贊 140 用戶, 點贊了這篇動態!
點贊

Add a new 評論

Some HTML is okay.