首页 > 解决方案 > Javascript:为什么 setCustomValidaty 在第一次提交时没有出现,但在第二次提交时出现了?

问题描述

我正在尝试验证登录表单,但我不明白为什么当我输入错误时,来自 setCustomValidation 的消息在我第一次单击提交按钮(实际上是输入)时没有显示的原因。但是,当我第二次单击同一个按钮时,会出现应有的错误消息。这是为什么?这是代码。

function validate(){

            console.log("check validate()")
            
            var email = document.getElementById("email");
            var psw = document.getElementById("psw");
            const patt =  /^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;

            if (email.value=="" && psw.value==""){
                email.setCustomValidity("You need to insert email and password!");
                return false;
            }

            else if ( email.value==""){
                email.setCustomValidity("Insert your email address");
                return false;
            }

            
            else if (psw.value==""){
                psw.setCustomValidity("Insert password");
                return false;
            }

            else if ( !patt.test(email.value) ){
                email.setCustomValidity("This is not an email!");
                console.log("Subcase works");
                return false;
            }

        }
<!DOCTYPE html>
<html lang="eng">
    <head>
        <meta charset="utf-8">

    </head>
    <body>
        <h1>Game</h1>
        <div>
            <form onsubmit="return validate()" method="POST" action="login.php">
                <input id="email" type="text" placeholder="email">
                <input id="psw" type="password" placeholder="password">
                <input type="submit" id="login-btn" value="Accedi">
            </form>
        </div>
    </body>
</html>

标签: javascripthtml

解决方案


首先,根据setCustomValidity 的文档

您必须在同一元素上调用 reportValidity 方法,否则不会发生任何事情。

第二次起作用的原因是,在设置自定义有效性消息时,当再次点击“提交”按钮时,浏览器内置的表单验证会接管并阻止提交。这就是您check validate()在后续提交时在控制台日志中看不到“”消息的原因。

因此,仅仅添加类似email.reportValidity()after youremail.setCustomValidity不是解决方案,因为在后续提交时,不会调用提交事件处理程序,因为由于非空自定义有效性消息,表单永远不会被提交。如果您尝试这样做,即使在填写了电子邮件和密码字段后,您也会看到相同的错误消息。要解决此问题,您可以添加novalidate到表单以绕过浏览器验证,也可以在输入更改时使用输入的onchange事件清除自定义有效性消息。

这是一个通过添加novalidate到表单并使用reportValidity().

function validate(){

            console.log("check validate()")
            
            var email = document.getElementById("email");
            var psw = document.getElementById("psw");
            const patt =  /^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;

            if (email.value=="" && psw.value==""){
                email.setCustomValidity("You need to insert email and password!");
                email.reportValidity();
                return false;
            }

            else if ( email.value==""){
                email.setCustomValidity("Insert your email address");
                email.reportValidity();
                return false;
            }

            
            else if (psw.value==""){
                psw.setCustomValidity("Insert password");
                psw.reportValidity();
                return false;
            }

            else if ( !patt.test(email.value) ){
                email.setCustomValidity("This is not an email!");
                email.reportValidity();
                console.log("Subcase works");
                return false;
            }

        }
<!DOCTYPE html>
<html lang="eng">
    <head>
        <meta charset="utf-8">

    </head>
    <body>
        <h1>Game</h1>
        <div>
            <form onsubmit="return validate()" method="POST" action="login.php" novalidate>
                <input id="email" type="text" placeholder="email">
                <input id="psw" type="password" placeholder="password">
                <input type="submit" id="login-btn" value="Accedi">
            </form>
        </div>
    </body>
</html>

这是一个onchange在输入字段上使用事件并使用reportValidity(). 请注意,在这种情况下,onsubmit仅在清除有效性消息后才调用处理程序,而不是每次单击提交按钮时调用。

function validate(){

            console.log("check validate()")
            
            var email = document.getElementById("email");
            var psw = document.getElementById("psw");
            const patt =  /^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;

            if (email.value=="" && psw.value==""){
                email.setCustomValidity("You need to insert email and password!");
                email.reportValidity();
                return false;
            }

            else if ( email.value==""){
                email.setCustomValidity("Insert your email address");
                email.reportValidity();
                return false;
            }

            
            else if (psw.value==""){
                psw.setCustomValidity("Insert password");
                psw.reportValidity();
                return false;
            }

            else if ( !patt.test(email.value) ){
                email.setCustomValidity("This is not an email!");
                email.reportValidity();
                console.log("Subcase works");
                return false;
            }

        }
<!DOCTYPE html>
<html lang="eng">
    <head>
        <meta charset="utf-8">

    </head>
    <body>
        <h1>Game</h1>
        <div>
            <form onsubmit="return validate()" method="POST" action="login.php">
                <input id="email" type="text" placeholder="email" onchange="event.target.setCustomValidity('')">
                <input id="psw" type="password" placeholder="password" onchange="event.target.setCustomValidity('')">
                <input type="submit" id="login-btn" value="Accedi">
            </form>
        </div>
    </body>
</html>


推荐阅读