blogWithMarkdown
blogWithMarkdown copied to clipboard
button不只是button
今天写前端页面的时候发现了一个有趣的事情,或者说bug吧。点击一个按钮,会导致页面跳转到404。查了下浏览器请求,发现是一个POST请求导致的。这个页面包含了一个form
,确实是想让它POST数据给后台。不过按照设定,应该是通过AJAX实现的,而不是直接重新加载页面。
看来不知道是什么触发了表单的submit事件。仔细阅读下相关的代码,这个按钮被按下时,会去检查表单是否正确,如果正确,则通过AJAX去进行POST。注意,这个按钮只是普通的<button>
,并不是<input type="submit">
。然而在页面跳转的同时,检查表单正确性部分的代码也不能工作了。
因为浏览器在POST之后会重新加载内容,不会保留之前的log,这给调试带来了麻烦。花了我不少时间,终于把bug揪出来了。原来是某一个分支中,event.preventDefault()
被绕过了,导致原来的事件没有拦住。一开始发现这一点时,我是感到很奇怪的,原来的事件不只是click
么?怎么会是submit
呢?
查了下,原来button
元素默认是type="submit"
,也即在form
中,点击button
自然会触发submit
事件。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<form action="/test" method="post">
<button>don't submit</button>
</form>
</body>
</html>
即使这个button
已经标明是“don't submit”了,呵呵。
解决之道很简单,就是指定type="button"
,这样它就是人畜无害、天真无邪的好button了。
如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<form action="/test" method="post">
<button>submit</button>
<button type="button">don't submit</button>
</form>
<button>just click it</button>
</body>
</html>
如果这个button
在form
之外,那么就不会触发submit
事件。然而在html5标准中,你可以通过设置form="#form_id"
属性来给button
指定一个非直系祖先的form
。
这篇debug小文本来打算发到SegmentFault上的,不过考虑到它实在太短,干货还不够多,所以就放到这里了。
cool! Thanks a lot!
牛逼,我今天也碰到了,写在form中完全是为了方便布局好看,我还以为是其他的js库把form里面的button的click事件给拦截了,按照你说的的确解决了问题
这个很好,非常感谢解决了我的问题,按钮在form里面,本来是设置了ajax的post方法,点击直接提交本页面了,一直失败,原来是属性的问题,十分感谢!!