如何在 "setCustomValidity("...");" 之后清除、删除或重置 HTML5 表单验证状态?

Posted

技术标签:

【中文标题】如何在 "setCustomValidity("...");" 之后清除、删除或重置 HTML5 表单验证状态?【英文标题】:How to clear, remove, or reset HTML5 form validation state after "setCustomValidity("...");"? 【发布时间】:2011-11-13 12:08:07 【问题描述】:

setCustomValidity("..."); 之后如何清除、移除或重置 html5 表单验证状态?

在 Firefox 和 Chrome 中设置一个空字符串 setCustomValidity(""); 会关闭表单验证错误消息。我不想关闭表单验证错误消息。我想重置验证状态,以便可以检查下一个答案并保留显示的验证错误消息。如果验证状态没有重置,那么即使是下一个正确答案也会错误地显示验证错误消息。


所以不知何故,“清除”意味着“关闭”?

如果参数是空字符串,则清除自定义错误。

http://www.whatwg.org/specs/web-apps/current-work/multipage/association-of-controls-and-forms.html#the-constraint-validation-api


这是一个验证测试用例:

<!DOCTYPE html>
<html dir="ltr" lang="en">
    <head>
        <meta charset="utf-8"/>
        <title>Validation test case</title>
    </head>
    <body>
        <form id="testForm">
            <input type="text" id="answer" pattern="[A-Za-z]+" autofocus required/>
            <input type="submit" value="OK"/>
        </form>

        <script>
            /*jslint browser: true, vars: true, white: true, maxerr: 50, indent: 4 */
            (function ()
            
                "use strict";

                var form = null;
                var answer = null;

                var isCorrectAnswer = function (value)
                
                    return (value === "a");
                ;

                var closeValidation = function (element)
                
                    // Close the form validation error message if displayed.
                    element.blur();
                    element.focus();
                ;

                var validateForm = function (event)
                
                    event.preventDefault();
                    event.stopPropagation();

                    var isValidForm = event.target.checkValidity();
                    if (isValidForm)
                    
                        if (isCorrectAnswer(answer.value))
                        
                            form.reset();
                            closeValidation(answer);

                            console.log("Correct answer.");
                            alert("Correct answer.");
                        
                        else
                        
                            console.log("Incorrect answer.");
                            answer.setCustomValidity("Incorrect answer.");
                            answer.checkValidity();
                            //answer.setCustomValidity("");
                        
                    
                ;

                window.addEventListener("DOMContentLoaded", function ()
                
                    form = document.getElementById("testForm");
                    answer = document.getElementById("answer");

                    form.addEventListener("submit", validateForm, false);
                , false);
            ());
        </script>
    </body>
</html>

键入一个错误答案,除“a”之外的任何字母,然后按 Enter。 输入正确答案“a”,然后按 Enter。

在不更改测试用例的情况下,Opera、Firefox 和 Chrome 中的行为是相同的(除了 Chrome 错误)。无论答案是正确还是不正确,验证错误消息都会持续存在。

现在,在取消注释answer.setCustomValidity(""); 之后,Opera 会清除自定义验证错误但不会关闭验证错误消息,这正是我所期望的。另一方面,Firefox 和 Chrome 都清除了自定义验证错误并关闭了验证错误消息(错误?)。


BUG: Chrome 在第一次调用时没有“checkValidity()”。

在 Chrome 中,answer.checkValidity(); 在首次提交后不会显示验证消息。后续提交显示验证错误消息。

http://code.google.com/p/chromium/issues/detail?id=95970

BUG:在 Chrome 中,输入更改时验证错误消息为空白但未关闭。

http://code.google.com/p/chromium/issues/detail?id=95973


Opera 11.51 Build 1087

火狐 6.0.2

谷歌浏览器 13.0.782.220 m

【问题讨论】:

【参考方案1】:

如果在“提交”事件处理程序中调用 setCustomValidity(),则不会显示自定义验证消息。

@tkent:

我确认 Opera 11.50 符合您的预期,但 Firefox 6 和 Chrome 14 没有。

但是,根据标准,Chrome 的行为是正确的。

http://www.whatwg.org/specs/web-apps/current-work/multipage/association-of-controls-and-forms.html#form-submission-algorithm

    如果从 submit() 方法提交的标志未设置,并且 submitter 元素的 no-validate 状态为 false,然后交互 验证表单的约束并检查结果:如果结果 是否定的(约束验证得出的结论是 无效字段并可能通知用户)然后中止 这些步骤。 如果从 submit() 方法提交的标志未设置,则触发 一个可取消的简单事件,名为 submit,在表单中。如果 事件的默认操作被阻止(即如果事件被取消) 然后中止这些步骤。否则,继续(实际上是默认的 action 是执行提交)。

浏览器必须在“提交”事件之前调用交互式验证 被解雇。您需要在“提交”事件之前调用 setCustomValidity() 如果您希望浏览器显示验证消息。歌剧似乎 以错误的顺序处理这些步骤。注意 checkValidity() 在 你的代码无论如何都没有效果。 checkValidity() 从不显示 验证消息。

http://code.google.com/p/chromium/issues/detail?id=95970


[Bug 11287] 新:元素中的“setCustomValidity”调用应使用“oninput”事件...

@尼克:

元素中的“setCustomValidity”调用应使用“oninput” 事件...

http://lists.w3.org/Archives/Public/public-html/2010Nov/0186.html


Re: [whatwg] 表单元素无效消息

@Mounir Lamouri:

因此,您所做的是使元素在无效事件中有效 太晚了。在无效事件之后,Firefox 尝试显示 UI 使用validationMessage,它在 表格有效。如果你不想有 UI,你应该取消事件 完全但仍然取消提交。你应该使用 onchange/oninput(强调添加)如果您希望表单更改有效性状态 提交。

http://www.mail-archive.com/whatwg@lists.whatwg.org/msg23762.html


解决方法是使用“输入”事件处理程序而不是“提交”事件处理程序来验证输入。

<!DOCTYPE html>
<html dir="ltr" lang="en">
    <head>
        <meta charset="utf-8"/>
        <title>Validation test case</title>
    </head>
    <body>
        <form id="testForm">
            <input type="text" id="answer" pattern="[A-Za-z]+" autofocus required/>
            <input type="submit" value="OK"/>
        </form>

        <script>
            /*jslint browser: true, vars: true, white: true, maxerr: 50, indent: 4 */
            (function (console)
            
                "use strict";

                var form = null;
                var answer = null;

                var isCorrectAnswer = function (value)
                
                    return (value === "a");
                ;

                var closeValidation = function (element)
                
                    // Close the form validation error message if displayed.
                    element.blur();
                    element.focus();
                ;

                var validateForm = function (event)
                
                    event.preventDefault();
                    event.stopPropagation();

                    var isValidForm = event.target.checkValidity();
                    if (isValidForm)
                    
                        console.log("Correct answer.");
                        closeValidation(answer);
                        form.reset();
                    
                    else
                    
                        console.log("Incorrect answer.");
                    
                ;

                window.addEventListener("DOMContentLoaded", function ()
                
                    form = document.getElementById("testForm");
                    answer = document.getElementById("answer");

                    form.addEventListener("submit", validateForm, false);
                    answer.addEventListener("input", function ()
                    
                        // Only show custom form validation error message if the value matches the pattern.
                        if (answer.value.match(new RegExp(answer.getAttribute("pattern"))))
                        
                            answer.setCustomValidity(isCorrectAnswer(answer.value) ? "" : "Incorrect answer.");
                        
                    , false);
                , false);
            (window.console));
        </script>
    </body>
</html>

【讨论】:

tl;dr:不要在“提交”事件中使用 setCustomValidity。它应该在 'submit' 事件之前设置,例如在 'input' 或 'change' 事件中。 但为了获得一致的用户体验,我希望能够告诉用户某个特定字段有问题(例如,没有这样的用户),并使用与我的表单其余部分相同的 UI。跨度> 所以答案基本上是setCustomValidity(''):设置空白字符串会取消验证。 我刚刚点击了这个......它似乎在 chrome 和 safari 中工作,但令人惊讶的是不是 firefox......我输入了错误的字符串.. 验证(oninput 或 onchange)设置验证消息(自定义)世界上一切都很好。然后我去更正它,它的有效电子邮件仍然显示消息。我发现的另一个问题似乎发生在任何浏览器中(对于电子邮件)......是 test@test 通过......没有后缀 .com 或其他......这是怎么回事?

以上是关于如何在 "setCustomValidity("...");" 之后清除、删除或重置 HTML5 表单验证状态?的主要内容,如果未能解决你的问题,请参考以下文章

angularjs,知道如何在 ng-bind="" 中包含 ""

Python 如何在list里寻找一个数字

如何在 bigquery 中处理动态架构

如何在 C++ 中更改 printf("%.2f")

如何在 AFNetworking 中发布像 "register_id":"3" 这样的参数

如何在 bigquery 中查询数组?