JavaScript之無法form.submit()的錯誤

先說,為了找這個錯誤,花了超過八個小時,不寫下來實在對不起自己。
表單(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:

19 則留言:

  1. 路人甲路過,同樣為了一個submit花了一個上午
    感謝您的經驗

    回覆刪除
  2. 一個上午,也是四個小時。還好,好是花八個小時,只為了一個submit。^_^

    回覆刪除
  3. 還好先看到了,只多花了一個小時。 ^_^

    回覆刪除
  4. 感謝您的經驗,讓我不用再花一個早上解決這問題:D 不過這問題貌似是id 跟 function名稱相同導致的錯誤:P跟submit的關係不大。我是id='login' onclick='login(this.form)' 死掉的XD

    回覆刪除
  5. 感謝您的經驗
    讓我快速debug :)

    回覆刪除
  6. 挖賽~我只能說這個太重點了= =
    大大沒寫這一篇我還真沒發現原來是因為這樣
    感謝><

    回覆刪除
  7. 一樣遇到這個問題,因為看到你的文章省了不少時間,感謝分享。

    回覆刪除
  8. 和你遇到一樣的問題,感謝!

    回覆刪除
  9. 感謝你的文章,今天也花了一個上午debug相同的問題,只是我是name=submit!!

    回覆刪除
  10. 感恩您, 你的經驗真的解救無數蒼生, 包括其中痛苦的我

    回覆刪除
  11. ........記得很久以前就看過這個文章
    想不到昨天還是犯了類似的錯誤= ="
    不過我是寫了兩個相同的ID導致沒有抓到正確的....(汗

    回覆刪除
  12. 路人乙經過,曾經我寫過一個批次檔遇到bug,由於批次檔寫出bug時小黑窗是不會告訴你的而是直接閃退,最後抓蟲抓到從晚上室友先去睡到他睡醒...(估計也八個小時),然後才發現是批次檔名稱 subst 與內部 subst 指令重名,導致每次指令到那行就會呼叫自己,形成無窮迴圈...

    雖然我分享的跟 JavaScript 一點毛關係都沒有,不過千萬要記得...

    不要將檔案或物件取名為既有的指令或機定植!
    不然怎麼死的都不曉得...QAQ

    回覆刪除
  13. Thanks for your solution!!!!

    回覆刪除
  14. 前人跌過的坑必須學下來!!

    回覆刪除
  15. 推一個 我是把舊有的CODE 加正規表示式檢驗密碼的時候 用TEST這個指令匹配 沒想到就有CODE裡面有個ID叫TEST ....... 害我網頁一直400 ERROR ...........

    回覆刪除

感謝您的留言,如果我的文章你喜歡或對你有幫助,按個「讚」或「分享」它,我會很高興的。