form 表单
表单是 html 里面最常用到的东西了.
很多时候我们会写自定义的表单,或者直接用框架上层的方式, 比如用 Angular.
但是在做小项目的时候,可能没有必要上框架,那我们就会用到原生的表单了.
这里记入一下,比较冷门的细节.
validation
selectElt.setCustomValidity(string); empty string 等于 clear error
set 的时候并不会马上出现 error message, 在 submit 的时候才会.
一些常用的接口:
console.log(input.validationMessage);
console.log(input.validity);
在 form 里面的某一个 input 上按 enter 键, 游览器会寻找 form 里第一个 button (type = "submit" or type = "image" or no define type).
找到以后会 click 它. 所以这个 button 的 on click 事件会被触发.
另外,除了 input enter, 我们使用 tab 键 focus 到 button 并且按 enter 键, 游览器也是会点击这个 button 事件 (不管是什么 type 都是一样)
然后呢, button 被点击后, 如果这个 button 是 form 里面的 submit, image or no define type, 游览器会 submit 这个 form.
触发 onsubmit 事件.
note :如果你在 click event 上 preventDefault() 那么这个默认 submit 事件就没了咯。
另外, 我们如果使用 javascript 调用 form.submit(), form 的 on submitt 事件是不会触发的哦。
如果要模拟 form submit 可以用 dispatch event 的方式,这样 on submit 就会触发
form.dispatchEvent(new Event('submit'))
ajax form
再来, form submit 后,我们可以通过 let data = new FormData(formElement);
这样的方式来获取资料, 然后就可以使用 xhr 发请求了。
mutilple button 的情况
有一种奇葩的场景就是,一个 form 里面有超过一个 submit button
最古老的一种方式是,
<button type="submit" name="submitButton" value="ok"> <button type="submit" name="submitButton" value="cancel">
写上 name 和 value, 当 button click 时, 游览器会偷偷的把次 button 的 name 和 value 加入到 formData 里面,然后传去后端.
注意 : 如果拦截 submit 事件然后通过 new FormData(formElement) 方式获取的话,是获取不到这个 button 值得,你不能用这个方式去知道哪个按钮被点击了。
还有一种写法是
<form id="form" action="/submit" method="POST"> First name: <input type="text" name="firstName" value="derrick" ><br> last name: <input type="text" name="lastName" value="yam" ><br> <button id="firstButton" type="submit" formaction="/submit" formmethod="POST" >submit</button> <button id="secondButton" type="submit" formaction="/cancel" formmethod="POST" >cancel</button> </form>
这个情况下, 也是有点奇葩的,假设我点击 cancel button, form on submit 依旧触发,form.action 值是 /submit, 最后发送的 url 是 /cancel..
form.submit() 发送的 url 则是依据 form.action, 不受 button 影响哦.
最后说一下,项目开发的时候应该怎样做比较好.
1. 避开多个 button, 监听 on submit 事件, preventDefault, 然后使用 new FormData 配合 xhr 发请求.
2. 不要使用 javascript form.submit(), 因为这样不会触发 on submit, 要用 js submit form, 直接调用 on submit 的方法不就可以了咯.
以上.
在 form 里 input enter 会触发 first submit/image button 的 click 事件
button focus enter 也会触发 click
click 事件触发如果 type 是 submit or image 就会触发 form submit, form on submit 就会触发.
如果 click 事件被 preventDefault 那就不会 form submit 了
button 没有声明 type 那默认是被当 submit type 来用, 虽然 attribute type 依然 = null.
js 调用 form.submit() 不会触发任何 onsubmit 事件.