項目開發中遇到一個很奇怪的現象就是:隨便點開一個下拉控件,包括combo,combobox,databox,combogird等等,都會出現點開的panel面板正常,如果頁面有滾動條,一用鼠標滾輪滾動頁面,panel的位置就一直固定在原來的位置,不會隨着它所屬的控件一起移動。由於我們項目是自己修改過easyui的,所以我懷疑的改出來的問題,我就換上原版的easyui就沒這個問題了,證明懷疑是對的。
還發現同樣一個頁面,有個頁面有這樣的問題,有個頁面沒有這樣的問題,這兩個頁面唯一的區別就是有問題的頁面用easyui-layout渲染了的。一開始我以為是layout控件修改錯了,但經過層層排查后發現問題不出在這里。
我單獨建了個頁面把用到的easyui控件js源碼一個一個單獨加載,不一下子加載全部,這樣經過排除法終於確定錯誤是在jquery.combo.js上的問題了。然后再仔細閱讀源碼確定問題在showPanel這個方法上。對比改動發現原來是這么回事:
//沒有改過的easyui偽代碼 function showPanel(){ //上面代碼省略 function getLeft(){...}//獲得所屬控件的left相對位置 function getTop(){...}//獲得所屬控件的top相對位置 //亮點來了 (function(){ if(panel.is(':visible')){//如果panel在顯示 panel.panel('move',{ left:getLeft(), top:getTop() });//計算所屬控件的位置,然后移動到那個位置 setTimeout(arguments.callee,200);//0.2秒后再執行本方法 } })(); }
原來的代碼只要panel打開就會不停的計算位置然后移動過去,而我們改動會的代碼把這個方法只執行了一遍,沒有進行循環。所以造成了這個問題。
那么為什么又和layout控件扯上關系了呢,經過排查發現,經過layout控件渲染后里面的div的樣式屬性overflow會變成auto,也就是說里面的div會有滾動條,而不用layout渲染的話滾動條會出現在最父級iframe級別上。而panel的定位位置是根據iframe級的相對位置而定的。所以前一種情況下,滾動是里面的div,而panel定位在全局上位置沒變,所以會顯現出問題,而后一種情況,滾動的時候,相當於是全局一起滾動,所以就算panel位置不變也沒關系,所以沒有出現這樣的問題。
我想之前把代碼改成不循環計算可能是出於性能考慮,而且也沒遇到用layout渲染的情況,就這樣改了。但是我認為這個性能花費並不大,因為只是打開的時候才計算,只要鼠標點其他地方panel都不關閉的,我就把代碼改成要循環計算的了。解決問題。