ZK-1430 真是一個曲折離奇的故事,分上下兩集來講好了 XD
上集:召喚 v/hflex="min",結束這個 issue
起手布局是一個 bandbox
,然後 bandpopup
當中塞了一個 listbox
。
希望這個 listbox
只顯示 5 個 row 的大小,所以設了 rows="5"
,
但是 bandpopup
不會跟 listbox
一樣大,自己長自己的大小。
算 bug 嗎?
乍看之下很像 bug,但是如果把 bandpopup
當成普通的 layout 來想,
那麼設定 v/hflex="min"
用小孩的大小來決定自己的大小,就十分合理了。
所以召喚 v/hflex="min"
,結束這個 issue!
(謎之聲:這上集也太短了吧?)
下集:IE 不能動,還有什麼值得我心痛
隔了兩天,原 po 上來說:
喔喔... 用
v/hfex="min"
這招在 Firefox 上 ok...
但是為什麼 IE7 沒效果?
WTF... 什麼不好炸、偏偏炸在 IE 上啊啊啊啊 <囧>
中間曖昧讓人受盡委屈的劇情就跳過,到外傳再另外賣一次錢,直接跳重點。
問題炸點的 stack trace 大概是:
ComboWidget.open()
this.presize_() //實際是跑 Bandbox.presize_(),會回傳 true
zWatch.fireDown() //參數是 'onFitSize', bandpopup
zWatch.fireDown()
zWatch.fire()
_fire()
_visiChildSubset() //表象炸點
_visible()
zk.Widget.isWatchable_() //instance 是 Bandpopup
zk.Widget.isWatchable_()
zk(wgt.$n()).isRealVisiable(true)
jqzk.isRealVisiable() //實際炸點
因為 _visiChildSubset()
回傳空的 array,導致 _fire()
的 gun 沒東西可作,
所以 bandpopup
也就沒有真的去作 onFitSize
了。
而 _visiChildSubset()
會回傳空的 array,是因為他只打算回傳已經 visible 的東西。
所以一路得追到 jqzk.isRealVisiable()
當中。
jqzk.isRealVisiable()
本來是在 dom.js 裡頭,但(還)不知道在哪裡動了手腳,
真正執行的是 domie.js 當中的 jqzk.isRealVisiable()、
而且還是 IE 7 以下的才會這樣搞(所以用 IE9 模擬 IE7 也能重現問題)。
這裡的邏輯是從 bandpopup
開始沿著 DOM tree 一路檢查到 <body>
,
必須都要 visible 才回傳 true,否則回傳 false。
至於判斷是不是 visible 的方式,因為 strict 是 true,所以下面兩個都要成立
$n.css('display') != 'none'; //_visi0() 的內容
$n.css('visibility') != 'hidden';
而在 IE6 / IE7 上頭,第二個判斷會回傳 false,原因得回到 ComboWidget.open()
,
在呼叫 presize_()
之前,做了這樣的事情:
// throw out
pp.style.visibility = "hidden";
pp.style.left = "-10000px";
這裡的 pp
等於上頭的 $n
,所以第二個判斷就爆了。
一路回推回去會讓 _visiChildSubset()
找不到東西→沒東西 fire→bandpopup 沒調 size。
至於解法,目前是在 Bandbox.presize_()
掛上一段
if (zk.ie < 8) {
var pp = this.getPopupNode_();
if (pp) pp.style.visibility = "";
}
然後才去作 zWatch.fireDown('onFitSize', bp, {reverse: true});
。至少目前看起來沒問題...... [遠目]
外傳:翻譯翻譯,什麼叫做驚喜?
其實整個故事就是一個怪。
從最上層的 ComboWidget.open()
開始看,很難懂為什麼一開始呼叫了一次 this.getPopupNode_()
,
得到的值只用來設 pp.style
的 width,height 還是給死成 auto
。
然後中間除了呼叫 $pp.makeVParent()
之外好像也沒幹麼,
轉眼又去 call this.presize_()
然後再來一次 this.getPopupSize_()
?
那第一次的 getPopupSize_()
到底是要作什麼用的?
為什麼 pp.style.visibility
要設定成 hidden
?(寫 pp.style.left="-10000px"
還不夠保險?)
然後在 this.presize_()
之後再設成空字串?
以 zk.$extends(zul.inp.ComboWidget
當關鍵字去 search 的結果,
發現只有 Combobox
跟 Bandbox
是 extends ComboWidget
,那蓋這一層 OO 是為了什麼?
(讓別人比較不好 trace? XD)為什麼其他行為類似的 class 沒有跟著用?
難道在這裡也中了「未成年就這麼優」的毒嗎?又,
想把 pp.style.visibility = "hidden";
拿掉,行嗎?
想把 this.presize_()
那段挪到 pp.style.visibility = "hidden";
前頭去,行嗎?
至於為什麼 jqzk.isRealVisiable()
會在 IE7 以下跑另外一個版本?
當然,在 IE 上發生什麼事情都不意外 [誤],但當初踩到什麼雷、兩邊的邏輯哪裡不一樣?
今天想不判斷 visibility != "hidden"
,行嗎?
很自然地,越底層的東西就越不太可能錯、或著該說就越不敢去改。
所以在處理 ZK-1430 的時候就只能往後退退退... 退到黃線後頭去了
退到最末端的 Bandbox.presize_()
去硬幹,還好看起來這個 method 沒人想要呼叫。
但是這樣真的好嗎? 真的「對」嗎?
師爺,給我翻譯翻譯,什麼叫做驚喜?
所謂驚喜就是 refactoryComboWidget.open()
,接上他的腿!
(To be continue... [完全誤])
No comments:
Post a Comment