restrictions in question与CSS / JavaScript使用display:none或visibility:hidden CSS规则隐藏时的表单控件的可见性有关。限制定义为:
4.10.7.1.1 Hidden state
When an
input
element’s type attribute is in the Hidden state […] Theinput
element represents a value that is not intended to be examined or manipulated by the user.[Also,]
- The
value
IDL attribute applies to this element and is in mode default.- The following content attributes must not be specified and do not apply to the element:
accept
,alt
,autocomplete
,checked
,dirname
,formaction
,formenctype
,formmethod
,formnovalidate
,formtarget
,height
,list
,max
,maxlength
,min
,multiple
,pattern
,placeholder
,readonly
,required
,size
,src
,step
,andwidth
.- The following IDL attributes and methods do not apply to the element:
checked
,files
,selectedOption
,selectionStart
,selectionEnd
,selectionDirection
,valueAsDate
,andvalueAsNumber
IDL attributes;select()
,setSelectionRange()
,stepDown()
,andstepUp()
methods.- The
input
andchange
events do not apply.
乍一看,说出验证不应该在用户控制的表单控件上执行。而且,对于使用默认表单控件元素构建的表单,这些都是有意义的。但现在,构建远程表单控件已经出现了一个问题。
HTML5和CSS3(也不是主要的浏览器)都使得样式窗体控件变得更加容易。 <选择>元素在造型方面仍然受到很大限制,并且< input>和< button>元素具有令人不安的不同风格规则(对于非IE浏览器,接近不可能的CSS浏览器定位)。因此,当我的设计师想要“漂亮”的表单控件时,它们可能需要使用HTML,CSS和JavaScript进行重建。模拟控件将远程控制CSS隐藏的实际控件。这适用于< select>,< input type =“checkBox”>和< input type =“radio”>在给定所需属性时,所有这些都会在WebKit浏览器中引起问题。
由于HTML5规范表明,某些属性(例如必需)不能存在于隐藏的表单控件上,所以浏览器将需要响应无效的属性。 WebKit浏览器通过不提交表单(而不是触发JavaScript的提交事件)进行响应。我现在遇到了一个< select>元件。
Chrome失败,并出现此错误到控制台:
An invalid form control with name=’element-name‘ is not focusable.
在窗口底部显示一个灰色条,并显示以下消息,Safari将失败:
Please select an item in the list
所以,我关心的是HTML5是否太限制,或者我正在接近这个问题。或者:
> HTML5的规范是有缺陷的,并增加了额外的限制,没有另一个解决方案。假设如果窗体控件不可见,则用户不应该与其进行交互。这样可以防止开发人员将HTML的验证属性用于我们远程控制的元素,同时将原始窗体控件隐藏起来。我们仍然没有能力使用CSS来创建我们的自定义控件,这需要我们自己来构建它们。
>我正在处理远程表单控件。由于我使用“旧”技术来解决可能重新定义的问题,所以我的方法可能已经过时了。还有可能的是,由于WebKit目前是唯一一个处理此限制的程序,因此WebKit有一个我尚未找到的解决方法。
目前我可以想到的唯一的解决方法是
>当我用JavaScript动态隐藏表单控件时,删除受限的属性,这意味着我牺牲了HTML5的验证,
>暂时显示并立即隐藏违规表单控件,尽管我不确定何时完成此操作,因为提交事件不会被触发,并且可以提交表单而不会在提交按钮上触发点击事件,或者
>使用novalidate属性,尽管我仍然会失去HTML5验证。
所以我正在看这个是正确的还是我错过的东西?
附:对不起长度。休息后的一切都是我的“tl; dr”。
解决方法
你的问题是另一个问题。你有一个真正的无效元素,它只能在视觉上被隐藏(使用display:none),并由另一个元素(或一组其他元素)替代。在您的情况下,问题如下:通过规范在交互式表单验证的情况下,浏览器必须集中第一个无效元素,并至少显示此元素一个验证消息。问题是,浏览器既不能集中隐藏的元素,也不能在该元素下面显示验证消息。这意味着浏览器停止表单提交,但是具有奇怪的UI来显示验证问题。
现在给你:这有道理吗?是的,它确实!如果您更改表单元素的UI,那么您还必须实现验证消息的UI。 (如果你想自定义某些东西,你已经定制了你想要使用的所有东西)。 HTML5给你一个API来实现这一点。
您必须绑定select元素的无效事件,然后阻止默认操作(如果它是表单的第一个无效事件),并将自己的验证工具提示放置到样式化的select元素。
在我的HTML5表单polyfill(webshims lib)中,我已经在使用代码链接一个本机元素(与API)和另一个生成简单验证工具提示的元素。
我创建了一个简单的jsfiddle,它模仿一个选择替换,并显示如何使用自定义表单控件实现HTML5表单验证。你可以找到example here。