You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多
文档控制台
免费开始使用

JavaScript表单验证异常:表单内容正确仍触发错误提示求助

解决表单验证总是触发错误提示的问题

嘿,我帮你找出问题所在啦,你的表单现在不管输入啥都会报错,主要是这几个小问题导致的:

  • 初始化时机不对:你在创建User实例的时候就获取了输入框的值,这时候用户还没输入内容呢,所以this.userName一开始就是空字符串,之后用户输入的内容根本不会更新这个变量,所以每次提交判断的都是最初的空值。
  • 回调函数的this指向错误onsubmit的回调函数里,this指向的是表单元素本身(也就是#myForm),而不是你的User实例,所以this.userName其实是undefined,条件this.userName == "" || this.userName == null永远成立,自然每次都报错。
  • 错误提示方式不友好:用document.write会直接覆盖整个页面,用户体验很差,咱们换成在表单下方显示提示的方式会更合适。

下面是修改后的完整代码,我把这些问题都修复了:

<html lang="en-US">
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width,initial-scale=0.1,shrink-to-fit=no">
    <link type="text/css" href="/css" rel="stylesheet">
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
    <title>Javascript Form Validation</title>
    <style>
    </style>
</head>
<body>
    <div class="container">
        <div class="row justify-content-center">
            <div class="col-sm-6 col-md-6 col-lg-6">
                <div class="card">
                    <div class="card-body">
                        <form method="post" name="myForm" id="myForm">
                            <div class="form-group">
                                <label for="exampleInputName1">Full name</label>
                                <input type="text" class="form-control" name="name" id="exampleInputName1" aria-describedby="nameHelp" placeholder="Enter name">
                            </div>
                            <!-- 添加错误提示容器 -->
                            <div id="error-message" class="text-danger mt-2"></div>
                            <button type="submit" name="login" class="btn btn-primary">Submit</button>
                        </form>
                        <script>
                            class User {
                                constructor() {
                                    // 保存输入框和表单元素,而不是初始值
                                    this.nameInput = document.myForm.name;
                                    this.form = document.getElementById("myForm");
                                    this.errorElement = document.getElementById("error-message");
                                }
                                submitForm() {
                                    // 用箭头函数保证this指向User实例
                                    this.form.onsubmit = (e) => {
                                        // 每次提交时获取最新的输入值
                                        const userName = this.nameInput.value.trim();
                                        // 清空之前的错误提示
                                        this.errorElement.textContent = "";
                                        
                                        if(userName === "" || userName === null) {
                                            this.errorElement.textContent = "Name Required";
                                            // 阻止表单默认提交行为
                                            e.preventDefault();
                                            return false;
                                        }
                                        // 验证通过,表单正常提交
                                        return true;
                                    }
                                }
                            }
                            let user = new User();
                            user.submitForm();
                        </script>
                    </div>
                </div>
            </div>
        </div>
    </div>
</body>
</html>

我主要做了这些修改:

  1. 构造函数里不再直接获取输入值,而是保存输入框、表单和错误提示的DOM元素,这样可以随时获取最新的输入内容。
  2. 用箭头函数作为onsubmit的回调,确保this始终指向User实例,不会跑偏。
  3. 每次提交时才获取输入框的最新值,并且用trim()去掉首尾空格,避免用户只输入空格的情况。
  4. 添加了专门的错误提示容器,用修改元素内容的方式显示错误,不会覆盖页面。
  5. 验证不通过时调用e.preventDefault()阻止表单提交,验证通过则正常提交。

这样修改后,只有当输入框为空(或只含空格)时,才会显示错误提示并阻止表单提交,输入正确内容就能正常提交啦~

内容的提问来源于stack exchange,提问作者GoodnessGoodness Chi

火山引擎 最新活动