比較懶,好久沒寫博客了,昨天遇到個問題隨手記錄一下
以前沒遇到這個問題,一直以為時間戳是可以作為類似於主鍵一樣的唯一標識。直到昨天遇到個老項目,出了個奇怪的bug。
項目是別人做的老項目,我們在修改,昨天測試告知說某輸入框,有時候能輸入東西,有時候內容會被清空。
看了頁面,清空的很明顯是表單驗證控件類型錯誤,本來該是單純必填的文本
,變成了數字
。問題在於這個有時候會變,有時候不會。
該開始對於問題的定位方向不對,以為是所用插件版本過老,插件的問題。
費老大勁查看壓縮的代碼、跟斷點,卻發現所有調用控件的,都是有控件特定class的元素,並沒有問題,然后懷疑不是插件問題,是調用之前就出問題了。
在插件數字控件numberbox初始化的地方用了console.trace(),查看調用棧

發現第一次非控件調用文件是utils.js 進去以后查看代碼,果然發現了問題
function initValidatebox(parent) { var children = parent.find(".easyui-validatebox,.easyui-combobox,.easyui-combo,.easyui-combotree,.easyui-combogrid,.easyui-numberbox,.easyui-datebox,.easyui-datetimebox,.easyui-spinner,.easyui-numberspinner,.easyui-timespinner"); if (children && children.length > 0) { $.each(children, function(i, n) { if ($(n).attr("data-options")) { var vali_rule = eval("[{" + $(n).attr("data-options") + "}]")[0]; var ntime = new Date().getTime(); $(n).attr("autovali", ntime); var ecss = []; var csss = $(n).attr("class").split(" "); $.each(csss, function(ci, css) { if (css.indexOf("easyui") > -1) { ecss.push(css.replace("easyui-", "")); } }); if (ecss && ecss.length > 0) { $.each(ecss, function(ci, css) { try { eval("$('[autovali=\"" + $(n).attr("autovali") + "\"]')" + "." + css).apply($('[autovali="' + $(n).attr("autovali") + '"]'), [ vali_rule ]); } catch (e) { } }); } } }); } }
//方法不復雜,關鍵在於下面的幾行代碼 var ntime = new Date().getTime(); $(n).attr("autovali", ntime); . . . eval("$('[autovali=\"" + $(n).attr("autovali") + "\"]')" + "." + css).apply($('[autovali="' + $(n).attr("autovali") + '"]'), [ vali_rule ]); //可以看到加了一個屬性,值為時間戳。"." + css 和apply是調用插件和綁定對象,這不是重點,重點是他選擇元素的的使用使用時間戳為選擇依據
意識到問題所在,驗證是否正確。把斷點打在這個方法里,多次觸發,直到出現bug時慢慢跟。頓時發現錯誤原因
原來,在代碼中時間戳並不唯一。應該是現如今電腦運行速度已經很快,循環中兩個相鄰元素加上的時間戳有可能一樣。

這就導致了當循環到第二個元素(市場價),給其初始化時,$('[autovali=\"" + $(n).attr("autovali") + "\"]')選擇了兩個元素,
從而導致前一個元素(屬性名稱)使用的控件種類(文本),被后一個元素的控件種類(數字)覆蓋。也就導致了時隱時現的bug。畢竟並不是每一次循環都出現相鄰元素加上的時間戳一樣。
問題找到就好解決了,我選擇最省時省力的
//$(n).attr("autovali", ntime); $(n).attr("autovali", ntime + "" + Math.floor(Math.random()*1000)); //把標識由時間戳,改為時間戳加隨機1-3位的數字
總結,時間戳並不適合單獨作為唯一標識,尤其是循環中加的時間戳
