在表单中使用 setCustomValidity 需要点击两次 onsubmit

Posted

技术标签:

【中文标题】在表单中使用 setCustomValidity 需要点击两次 onsubmit【英文标题】:Use of setCustomValidity in form requires two clicks for onsubmit 【发布时间】:2014-04-23 03:49:08 【问题描述】:

我正在开发一个表单,该表单将 html5 表单验证属性 required 用于各种 textradio 按钮字段。该表单还有两组复选框,其中至少一个复选框必须被选中。

为了保持用户错误反馈的一致性,我使用setCustomValidity 方法在未选中复选框时抛出本机错误气泡。这一切都很好,但是,当提交表单并且onsubmit 事件用于捕获未选中的复选框时,会出现错误反馈问题。当onclick 事件被绑定到提交按钮时不会出现此问题,但我知道最好使用onsubmit

Onclick 测试用例(点击提交按钮第一次出现错误气泡!) http://jsfiddle.net/Jimadine/bZe5e/

Onsubmit 测试用例(点击提交按钮 - 第二次点击后出现错误气泡) http://jsfiddle.net/Jimadine/2vLszqac/

此外,根据我对 onsubmit 案例的测试,Firefox 在第一次单击提交按钮后会突出显示未选中的复选框;这由复选框周围的红色光芒表示。然后在第二次单击后显示错误气泡。在其他现代浏览器中,第一次单击不会在屏幕上显示未选中复选框的指示;我认为这就是 HTML5 验证的 UX 方面在这些浏览器中实现的方式,而 Firefox 选择做的事情略有不同。

我的问题是为什么 onsubmit 测试用例需要两次点击,什么是纠正这个问题的合适方法,使其表现得像 onclick 测试用例?我猜这与验证后触发的提交事件有关,但我不确定如何更正我的代码。

【问题讨论】:

如果我理解正确,您正在设置 setCustomValidity 而表单提交已经发生。您必须在提交表单之前设置它们,即在您呈现表单时。 是的,你理解正确。从那以后,我发现了一篇博客文章,其他人遇到了类似的问题 (goo.gl/eGks5b) 那么如何在表单加载时分配验证规则呢?你有什么简单的例子吗?如果我的自定义复选框验证以与具有 required 属性的单选和文本控件相同的方式触发,那将会更加整洁。 我已经阅读了所有关于在提交之前执行 setCustomValidity 的内容;但是,在某些情况下,提交确实是我需要的。 (单击时不能按回车键。)服务器通常会告诉我哪些字段不好,并且只有在所有字段都填满时才能这样做。 (也不能依赖最后填写的最后一个字段。)真的有一个黑客可以在提交时设置自定义有效性...... 当在提交按钮的输入中切换并按下回车键时,我会触发 click 事件 - 刚刚尝试使用我的原始问题 (Chrome/FF/IE11) 中发布的 Onclick 测试用例 JSFiddle。你用的是哪个浏览器?也许你可以做类似 document.getElementById('your-input').onkeydown = function( e ) if ( e.keyCode === 13 ) targetElement.setCustomValidity("Your message"); 最后的想法:您可以尝试在您的 onsubmit 处理程序上使用 e.preventDefault(),在您的 setCustomValidity 代码之前 - 如果您必须使用 onsubmit。 【参考方案1】:

我遇到了一个类似的问题,对我来说它可以调用 reportValidity() 紧跟在 setCustomValidity() 之后。

function onSubmit(e)
  e.preventDefault();

  const myInput = document.getElementById('my-input');

  if( inputIsInvalid )
    myInput.setCustomValidity('My custom invalidity message.');
    myInput.reportValidity();
  

参考:https://developer.mozilla.org/en-US/docs/Web/Guide/HTML/Constraint_validation#constraint_validation_process

【讨论】:

【参考方案2】:

这是一个基于您的第一个示例 http://jsfiddle.net/bZe5e/6/ 的工作 jsfiddle。

关键不是仅在提交/按钮单击时执行此操作。您最初正在检查 change + 的有效性

doValidate();

【讨论】:

谢谢 :) 最初运行该函数会导致验证检查在用户开始填写表单之前进行,这是不可取的。在 Firefox 中,这会在第一个复选框周围发出红光。我想我只是希望我的自定义验证与 HTML5 属性验证(例如必需、模式等)同时触发 其实它是这样工作的。必填字段和空白字段从一开始也是无效的。 firefox 渲染红色轮廓/框阴影的事实确实很烦人。也可以在这里查看:bugzilla.mozilla.org/show_bug.cgi?id=655677 有趣。您的错误报告解释了 Firefox 的行为,这似乎与其他现代浏览器形成对比。谢谢 - 您提供了一些有用的回复。

以上是关于在表单中使用 setCustomValidity 需要点击两次 onsubmit的主要内容,如果未能解决你的问题,请参考以下文章

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

HTML5应用:setCustomValidity(message)接口

html5 验证需要 setCustomValidity

element.setCustomValidity 似乎不起作用

JavaScript 验证 API中的setCustomValidity()方法

如何在表单提交之前立即在无线电输入上设置自定义值