西杰技術分享

做mix2ool的template元素時發現的一個問題。在IE中,當我set innerHTML時,如果我要加入的element不是標準的element(e.g. <a> <div> ),IE就不會把style 應用到那些element了。

解決方法是這樣的,雖然使用innerHTML來加入element有問題,但如果加入document.createElement產生的element卻是可以成功的。因此,只要用這些DOM方法把要設定的html轉為DOM element就可以了。可幸的是,這個工作已經有人做了。

innerDOM

這個innerDOM可以把string轉為DOM,把DOM轉為String。


近期在搞Mix2ool,是mix framework的進化版,這次view engine由B/S 轉為C/S架構,大量使用了javascript。

其中寫了這麼的一段

1
2
3
4
5
6
7
8
9
10
11
mix.Bindable.bindingFunc = function (n, old, vari){
	var b = $(this).attr("binding");
	if (b == null) b = "";
	var context = this;
	b.replace(" ", "").split(";").removeNothing().each(function (v){
		var t = v.split(":");
		if (t[1] == vari){
			$(this).attr(t[0], n);
		}
	}, this);
};

就是做binding的工作,然而卻產生了too much recursion的問題,因為當我setAttribute的時候,下一個element也會notify一個attrChange event,那個event同時又做了binding的工作,結果bind得沒完沒了。

解決方法是把$(this).attr(t[0], n)放在一個新的closure中進行

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
mix.Bindable.bindingFunc = function (n, old, vari){
	var b = $(this).attr("binding");
	if (b == null) b = "";
	var context = this;
	b.replace(" ", "").split(";").removeNothing().each(function (v){
		var t = v.split(":");
		if (t[1] == vari){
			if (mix.Bindable.stacked &gt; mix.Bindable.maxStack){
				//if there are too many stacked event handlers, browsers will stop running due to "too much recursion"
				mix.Bindable.stacked = 0;
				(function(){ //this method is generally slower in performance, so use different methods alternatively
					$(context).attr(t[0], n);
				}).once(0);
			}else{
				mix.Bindable.stacked++;
				$(this).attr(t[0], n);
			}
		}
	}, this);
};

把.attr()放在一個function之中並在0微秒之後執行(setTimeout),可以在這個closure的執行者設為window,而不是mix.Bindable.bindFunc,那就可以解決問題了。然而,如果把所有工作都放到新的function內執行,setTimeout產生出來的delay會很明顯,因此我用了mix.Bindable.stacked來記錄recur了的次數,當recur到一定大的地步才會在新的function執行,這可以加快一點速度。

P.S.其實這個方法不太好,現在我在想其他方法。


這兩天開始新project了,這次不是唱獨腳戲了,而是與數人合作,亦因此有分工問題。我們三個programmer將會使用PHP JS HTML等等技術來開發一個網站,而程式架構將會是MVC的,問題就是我們的工作時間不一,有人可以早上做,有人晚上做,如果一人負責一部份(M、V、C),那很可能會做成C要等V完成才可以繼續寫,而且每次開始之前亦要先回顧V做過的東西,做不到同步開發,那麼便失去了分工的意義。更恐怖的是C要等V做完才可以測試,或者要另外寫tester來測試,浪費十分多的時間。

因此,我們研究了另一個開發模式,是橫分MVC,以模組為單位,如登入是一個功能模組,搜尋是一個功能模組,每個模組的MVC都由同一人開發,而每個模組之間亦保持高度分離。如果模組間要溝通(例如搜尋模組可分為搜尋框和結果列表),就會使用observer pattern來連接,即建立一個全局的事件處理機制,當搜尋完結時便fire一個event,讓結果列表(observer)更新自己的資料。

另外,為減少回顧別人寫的code 的時間,我們亦設計了一個新的程式碼架構,架構是把Controller的action分開成不同file,並且把JS、PHTML(template檔)分開成多個file,要使用時才載入,以避免測試時會受到別人的syntax error影響。唯一美中不足的是,PHP的物件機制不夠動態,Model很難做到分開數個檔案並動態載入,所以只能夠把Model的method寫在同一檔案。

Skeleton - 這是我們的開發模式骨架。


做好了一套高登+的API了,開發者可以在此看到高登+API文檔


這數天都在做一個網站流量統計的程式,其中一步是要找出每小時的人流。很直觀的,我會使用GROUP BY來處理,然而,這就出現了一個問題。如果有其中一小時沒有人來過網站的話,資料庫內就沒有那一小時的資料,那麼就會出現在每小時的人流統計中缺少了一小時的資料(那小時的人流該為0,現在卻是少了這筆資料)。要解決的方法有很多,但西杰程式的標準是高效和代碼優雅,這確然令我少了很多選擇。 More»


剛才在寫一個將IP轉換為國家名稱的程式,使用了市面上提供的IP文字資料庫。資料庫官網建議使用mysql資料庫來記載資料,然而,如果mysql資料庫和PHP伺服器的主機不同,要使用網絡來拿取資料的話,相信會比本機查找慢。於是,最後我決定封裝一個本機查詢IP資料的程式。 More»


花了兩天時間做了一個Wordpress的主題,就是大家現在看到的黑紅主題了,素材主要還是用西杰.NET的圖片。不得不提,麻煩的I.E.真的十分麻煩,用png圖片又不能直接做到透明效果,轉了gif質素又會變差,最後還是轉gif後自己一pixel一pixel的改動:(。

下載連結在這︰ westkit


今天寫程式時遇到一個問題,我希望動態載入一個語言檔(因為不同使用者可能會使用不同的語言),然而如果我異步地載入的話,可能語言檔未載入好就需要用了,那當然會出現runtime error。當然,我可以加入callback function,當語言檔載入好才執行callback function,那就可以解決runtime error,然而這樣寫的話程式碼會很不整潔,違反西杰寫程式的原則:)。 More»


高登Core API是連接高登討論區的核心引擎,高登+和高登RSS都是使用此引撉開發的。

新增特色︰

  1. 加入skip list,可以避免使用某部份伺服器
  2. 加入替換連結功能,可以將貼文內的高登討論區連結轉為自己伺服器的連結

下載連結︰http://hkg.westkit.net/goldenCore-latest.tar.gz


有些時候,我們不想用瀏覽器預設的按鈕,我們會自己繪畫自己的按鈕。如果我們希望當鼠標經過按鈕時按鈕會有發光的效果,就需要換一張圖片了。然而,引申的問題就是,瀏覽器不會預先載入該圖片,而是當瀏覽器需要該圖片時才會再向伺服器要求該圖片,當中會有一段時間差,這就是閃爍現象。這是一個不好的用戶體驗,突如其來的一閃很可能會嚇怕你的觀眾啊! More»