某個網頁出現<input type="submit"> onclick事件return false;卻無法阻止Postback的情況,進一步測試發現問題只出現在IE7/8,表單在IE9則如預期會因onclick事件回傳false取消Postback。

使用刪去法,將網頁元素及程式一點一點移除並反覆測試,終於查出問題所在,答案有點離奇,竟是因為網頁使用了jQuery BlockUI的$(element).block()造成異常。深入jquery.blockUI.js原始碼,更進一步鎖定問題來源,網頁所用的jquery.blockUI 2.07版(經測試改用2.5.4新版時倒無此問題),於設定block層時會透過以下程式碼掛載document.onclick事件:

// bind anchors and inputs for mouse and key events
var events = 'mousedown mouseup keydown keypress click';
b ? $(document).bind(events, opts, handler) : $(document).unbind(events, handler);

而在handler函數最後一行為:

// allow events for content that is not being blocked
return $(e.target).parents().children().filter('div.blockUI').length == 0;

推敲其用意是在全網頁被.blockUI()遮蔽時,故意傳回false以取消對document的所有滑鼠及按鍵操作! 在這個案例中,使用了block(),handler事件會生效,但由於非blockUI(),故document.onclick時預期將return true; 透過IE Dev Tools偵錯程式碼,在按下送出鈕時,<input type="submit"> onclick事件return false,document.onclick卻return true,同一個click動作出現兩個不同的return值,故有可能是IE7/8/9對此一情境的行為不同所致。

整理成一個重現問題的極精簡範例:

<%@Page Language="C#"%>
<script runat="server">
    void Page_Load(object sender, EventArgs e) 
    {
        if (IsPostBack) {
            Response.Write("PostBack!");
            Response.End();
        }
    }
</script>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title>Test Return False</title>
</head>
<body onclick="return true;">
    <form id="form1" method="post" runat="server">
        <input type="submit" value="Submit"  onclick="return false;"/>
    </form>
</body>
</html>

這個網頁在使用IE7/8相容模式檢視時,按下Submit鈕,即便onclick="return false"仍會觸發PostBack。使用IE9/Chrome/Firefox則不會PostBack,算是驗證了此一行為差異。

一個簡單的解決方案是修改送出鈕onclick事件,除了return false再加上event.returnValue = false,如此即可在IE7/8/9/Chrome/Firefox均順利運行:

<input type="submit" value="Submit"  onclick="if (event) event.returnValue = false; return false;"/>


Comments

Be the first to post a comment

Post a comment