表單(Form),通常會先寫一些validate的javascript,今天碰到一個教科書上沒教的事,我們先看form:
<form method="post" action="submit_form.html"> <input type="text" id="test" /> <input type="button" id="submit" value="Send" /><br /> <span id="test_help"></span> </form>
就一個TextBox與一個Button,span是拿來放訊息的,接下來我們寫個簡單的validateNonEmpty函式,驗證TextBox裡為是沒有資料即可:
function validateNonEmpty(form){ if (document.getElementById('test').value.length != 0){ form.submit(); } else { var help = document.getElementById('test_help') help.innerHTML = "No Data."; } }
使用傳統HTML加上onclick事件:
<form method="post" action="submit_form.html"> <input type="text" id="test" /> <input type="button" id="submit" value="Send" onclick="validateNonEmpty(this.form)" /><br /> <span id="test_help"></span> </form>
測試一下,發現在無資料時,Javascript可以正常運作,但在有資料時,Firebug會出現:
form.submit is not a function
http://127.0.0.1:8000/html/submit_form.html
Line 9
怪怪,明明就是form元素的submit,為什麼跟我說submit不是個函式,又不是沒寫過??????????之前我會花超過八個小時是因為那個表單又是Javascript又是jQuery,而且欄位又多,Debug起來費心費力,因為不確定是我寫的原生Javascript出錯,還是jQuery有錯,而且如果你頁面有引用jQuery的話,Firebug還會把錯放到jQuery身上,讓我一度以為我怎麼那麼厲害,隨便寫寫都能抓到JQuery的bug。所以在抓Bug時要使用「簡單原則」,如我能像上面一樣用簡單的作法,先進行測試,那…@_@…我的青春!
為了讓網頁架構分明,所以們我們會分離「架構(XHTML)、行為(Javascript)、樣式(CSS)」,所以在原始抓bug的網頁裡我是用jQurey來bind()事件,所以整體是這樣:
function validateNonEmpty(form){ if (document.getElementById('test').value.length != 0){ form.submit(); } else { var help = document.getElementById('test_help') help.innerHTML = "No Data."; } } $(function(){ $('#submit').bind('click',function(){ validateNonEmpty(this.form); }); });
<form method="post" action="submit_form.html"> <input type="text" id="test" /> <input type="button" id="submit" value="Send" /><br /> <span id="test_help"></span> </form>
這時會產生一樣的錯誤。很多事沒有你想的複雜。後來我不斷思考(看著錯誤訊息)及測試終於找出問題點。
id="submit"是兇手
原因是button裡的id="submit",因為我們要使用jQuery來bind(),所以為button加上了id屬性,這此按鍵又是拿來發送,所以很直覺給它一個submit名稱,沒想到一個submit要花八個多小時來處理。當你把名稱修改為非submit,例如id="send",程式立即生效,我想是這是id名稱與函數名稱「強碰」所造成的錯誤。由錯誤訊息推估,當我們執行form.submit()的取得是button這個物件,而非submit()方法。自己被自己害到!
這也讓自己再學到一個經驗,取Javascript名稱不要與Javascript方法同名。還我八小時@_@。
Reference: