聯絡表單裡新增一個「查看說明」按鈕,點下去卻重新載入頁面,甚至把還沒填好的資料送出去。先看按鈕的 type,再查腳本。一般與表單關聯的 button,如果沒有明確指定用途,可能被當成提交按鈕。
同一個畫面中,「查看說明」只需要操作介面,「送出需求」才需要提交。把用途寫進 HTML,通常比在每個 click 事件裡另外阻止送出更容易維護。
先確認這個按鈕屬於哪個表單
在開發者工具選中按鈕,看它是否位於 form 裡,以及有沒有 form 屬性指向另一份表單。按鈕不在表單標籤之內,也可能透過這個屬性成為表單的控制項,不能只看畫面位置判斷。
接著核對 type。這篇以沒有其他命令用途的普通表單按鈕為例:未指定 type 時,在瀏覽器中讀到的按鈕類型是 submit。原始 HTML 沒有這個字,不代表按鈕沒有提交行為。
<form action="/contact" method="post">
<button>查看說明</button>
</form>
上面的文字叫「查看說明」,瀏覽器仍按按鈕類型處理。CSS 把它畫成問號或小圖示,也不會改變用途。先查看輸出的實際 DOM,因為模板元件可能在渲染時加入或移除屬性。
介面動作用 button,提交用 submit
展開說明、切換分類、增加欄位或預覽內容,通常應使用 type="button"。它不會因這個原生按鈕行為提交表單,但仍需要自己的腳本處理要做的事。真正送出則明確寫 type="submit"。
<button type="button" id="show-help">查看說明</button>
<button type="submit">送出需求</button>
type="reset" 是回復表單控制項的初始值,不是關閉說明,也不是保留內容的取消按鈕。如果真的需要清除或回復,先讓訪客理解會失去哪些修改;不要只因按鈕寫「取消」,就套上 reset。
在 Vue、React 或其他元件中,也核對 type 是否真正傳到原生 button。元件外層寫了屬性,內部卻沒有向下傳遞,瀏覽器仍可能使用另一種預設行為。以渲染後的元素為準。
本例點同一種說明入口,結果不同
我們在自建桌機頁面放入合成姓名欄位和三個按鈕。第一個說明按鈕沒有指定 type,第二個明確使用 button,第三個是正式的示範提交。表單只向本機 GET 入口發送合成資料,沒有寄信或保存任何客戶內容。
點第一個按鈕後,瀏覽器到達提交入口,網址帶有姓名查詢值。回到原頁,點第二個按鈕,則只更新「說明已開啟;姓名與頁面保留」,網址仍停在原表單。

這個對照核的是原生類型與請求行為。你的表單若有必填欄位,未填時可能先被瀏覽器驗證擋下,所以畫面未跳轉不代表那顆按鈕不是 submit。使用合成有效資料,再核對是否發出請求,才不會被其他條件遮住。
有 click 腳本,仍可能繼續提交
一個 click 事件先開啟說明,並不會自動取消原本的提交動作。這也是為什麼頁面可能閃過說明,接著立刻跳走。若用途本來就不是提交,先修 type,再保留需要的事件處理。
event.preventDefault() 可取消適用事件的預設行為,但要知道取消的是哪個事件。只在某一個 click 處理器阻止,可能漏掉其他提交途徑;需要自訂真正的送出流程時,通常在 form 的 submit 事件統一處理。
也要查腳本是否主動呼叫提交、改變網址或執行路由跳轉。加上 button 只移除它本身的原生提交用途,不會阻止你自己的程式呼叫其他動作。原生行為與腳本行為各自記錄,才能找出真正的跳頁原因。
Enter、表單入口與提交按鈕一起核對
訪客可能在輸入框按 Enter 提交。這是表單提交流程中的另一個入口,不能只修滑鼠點到的說明按鈕,就假定整份表單不再提交。先保留應有的 submit 按鈕,再確認 Enter 的用途符合表單設計。
不同提交按鈕也可能設定 formaction 或 formmethod,覆寫表單原本的入口與方法。如果某顆按鈕去了另一頁,除了 type,也看它是否另有這些屬性。不要一律把所有按鈕改成 button,讓真正送出失去功能。
對話框中的 method="dialog" 表單另有關閉用途,不是普通送資料入口。若正在處理彈窗內的按鈕,先核對它的表單方法;不要把本篇一般表單的請求結果套到所有 dialog。
改動只限錯誤用途的那顆按鈕
保存原來的 HTML 或元件,替不該提交的入口明確加上 button。接著用有效合成內容試一次說明、一次真正提交,再用 Tab 和 Enter 操作。確認欄位保留、說明可用、真正提交仍到達正確入口。
如果按鈕改了但仍跳頁,把渲染後 type、所屬 form、click 與 submit 處理器,以及實際請求網址交給維護者。不要先移除整份表單,或關掉所有驗證和提交腳本;修正應能對上那個不該發生的動作。

評論0