最近,公司某條產品線上的一個功能出了問題:點選查詢的時候,該頁面在IE上直接卡死,chrome上會卡頓一段時間候提交表單進行查詢。拿到這個bug單子以後,簡單重現了下,基本上定位到是查詢操作中的問題,我假設了兩個原因:1、在查詢之前傳送了什麼ajax請求去後臺做校驗,該請求很慢,卡死;2、在查詢之前,有大量的js計算,有效能問題。

那麼按照這個思路,我看了下業務線上寫的程式碼,直接找到了查詢的toSearch方法,簡單過了一遍,就定位到問題了,程式碼如下(模擬程式碼):

 <!DOCTYPE html>
<html>
<head>
<title>表單提交引發的血案</title>
<meta charset="utf-8">
<!--<script type="text/javascript" src="http://libs.baidu.com/jquery/1.7.2/jquery.min.js"></script>-->
<script type="text/javascript" src="../core/jquery-1.9.1.js"></script>
<script type="text/javascript">
function toSearch(event){
//TODO:這裡做了簡單的校驗
$("#myForm").submit(); } </script>
</head> <body>
<!--所有佈局都放在admin-main內部-->
<div>
<form id="myForm" action="http://www.baidu.com" method="post" onsubmit="return toSearch();">
<input type="text" id="username" name="username">
<input type="submit" value="提交">
</form>
</div> </body> </html>

看了這個程式碼,我相信大家也和我一樣看出問題來了,那就是重複提交,導致死迴圈。在js中又呼叫了submit方法去提交。正確的寫法是:驗證通過後,直接return true,否則return false即可。

為了驗證我的想法,然後在本地做了一個例子。例子如上,只不過toSearch方法中,並沒有用jq,而是直接用的原生js呼叫submit方法去提交,可是結果和我想象的並不一樣,表單直接提交了。這下子就引起了我極大的興趣了,為了一探究竟,看下jq的原始碼,然後又模擬了下,程式碼如下:

 <!DOCTYPE html>
<html>
<head>
<title>表單提交引發的血案</title>
<meta charset="utf-8">
<!--<script type="text/javascript" src="http://libs.baidu.com/jquery/1.7.2/jquery.min.js"></script>-->
<script type="text/javascript" src="../core/jquery-1.9.1.js"></script>
<script type="text/javascript">
function toSearch(event){
console.log("表單提交",new Date().getTime());
var oForm = document.getElementById("myForm");
//jquery的submit
// $("#myForm").submit(); //模擬jquery核心程式碼
var handle = oForm.onsubmit;
if ( handle && handle.apply(oForm, [event]) === false ) {
event.preventDefault();
}
} </script>
</head> <body>
<!--所有佈局都放在admin-main內部-->
<div>
<form id="myForm" action="http://www.baidu.com" method="post" onsubmit="return toSearch();">
<input type="text" id="username" name="username">
<input type="submit" value="提交">
</form>
</div> </body> </html>

原來jQ中對於submit方法,看了我模擬的jq,我相信大家已經明白了吧,jQ是拿著方法,用apply去執行,原生submit是直接提交了form表單。

問題雖小,也很簡單,但是更加堅定了我的信念:基礎是王道,還是要一步一個腳印,才能走的更遠。