<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-8035033083660504051</id><updated>2011-09-10T22:41:36.076+08:00</updated><category term='PHP'/><category term='function binding'/><category term='Watermark'/><category term='HTML5 Audio'/><category term='ImageMagick'/><category term='Mobile web'/><category term='Closure Compiler'/><category term='Deep linking'/><category term='JavaScript'/><category term='HTML5 Touch events'/><category term='GD2'/><category term='HTML5 Web Storage'/><category term='HTML5'/><category term='CakePHP'/><title type='text'>HK Geek Cafe</title><subtitle type='html'>香港人寫的技術文章</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://geek-cafe-hk.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8035033083660504051/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://geek-cafe-hk.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>茄糞男</name><uri>http://www.blogger.com/profile/03341897835591864475</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_GWMqAoJtc_M/TDsZxm0yZJI/AAAAAAAANWY/k-qiPsMRXio/S220/blog2.png'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>9</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-8035033083660504051.post-4340589687482436832</id><published>2011-07-22T00:10:00.004+08:00</published><updated>2011-07-22T01:24:59.808+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JavaScript'/><category scheme='http://www.blogger.com/atom/ns#' term='Mobile web'/><category scheme='http://www.blogger.com/atom/ns#' term='HTML5'/><category scheme='http://www.blogger.com/atom/ns#' term='HTML5 Touch events'/><title type='text'>可以觸摸的網頁</title><summary type='text'>HTML5 之中定義了對於 Touch Device 相應的功能. 其中最重要的大概是在 JavaScript 之中的 touch event.Touch event 跟 mouse event 某程度上相當相似. 三個 event 分別是 touchstart, touchmove 及 touchend. 這就好比 mouse event 當中的 mousedown, mousemove 及 mouseup 三個 event.不過, touch event 跟 mouse event 的最大分別, 就是它本身設計支援 multi-touch, 所以每個 event handler 接收回來的 event 會包含每一隻手指(或接觸點)相關的資訊. 先拿 touchstart event 做例子:document.getElementById('someid')  .</summary><link rel='replies' type='application/atom+xml' href='http://geek-cafe-hk.blogspot.com/feeds/4340589687482436832/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://geek-cafe-hk.blogspot.com/2011/07/blog-post.html#comment-form' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8035033083660504051/posts/default/4340589687482436832'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8035033083660504051/posts/default/4340589687482436832'/><link rel='alternate' type='text/html' href='http://geek-cafe-hk.blogspot.com/2011/07/blog-post.html' title='可以觸摸的網頁'/><author><name>茄糞男</name><uri>http://www.blogger.com/profile/03341897835591864475</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_GWMqAoJtc_M/TDsZxm0yZJI/AAAAAAAANWY/k-qiPsMRXio/S220/blog2.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8035033083660504051.post-1952793862581961362</id><published>2011-06-30T23:07:00.003+08:00</published><updated>2011-07-01T01:16:00.494+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JavaScript'/><category scheme='http://www.blogger.com/atom/ns#' term='function binding'/><title type='text'>令人又愛又恨的 JavaScript function</title><summary type='text'>JavaScript 的其中一個特別之處, 就是 function 本身是一種 object 這個設計. 習慣寫 procedural 及 OOP 的人一時間未必能夠完全消化箇中用處. 寫 C 的高手, 或者是學過 LISP 的人, 也許會比較容易明白. 不過同一時間, 當 function 跟 object 一齊使用時, 又帶出了更加麻煩的 binding 問題.JavaScript function 簡介要定義 JavaScript function, 最基本的方法就是直接用 function keyword 來定義function someFunc() {    // ... }這樣做的話, 其實等同於定義一個叫 someFunc 的 variable, 並指定一個 function object 作 value:var someFunc = function () {    //</summary><link rel='replies' type='application/atom+xml' href='http://geek-cafe-hk.blogspot.com/feeds/1952793862581961362/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://geek-cafe-hk.blogspot.com/2011/06/javascript-function.html#comment-form' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8035033083660504051/posts/default/1952793862581961362'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8035033083660504051/posts/default/1952793862581961362'/><link rel='alternate' type='text/html' href='http://geek-cafe-hk.blogspot.com/2011/06/javascript-function.html' title='令人又愛又恨的 JavaScript function'/><author><name>茄糞男</name><uri>http://www.blogger.com/profile/03341897835591864475</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_GWMqAoJtc_M/TDsZxm0yZJI/AAAAAAAANWY/k-qiPsMRXio/S220/blog2.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8035033083660504051.post-3883681004808725116</id><published>2011-06-29T00:29:00.006+08:00</published><updated>2011-06-29T01:16:49.935+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JavaScript'/><category scheme='http://www.blogger.com/atom/ns#' term='Closure Compiler'/><title type='text'>借用 Closure Compiler 來 debug JavaScript</title><summary type='text'>JavaScript 令人頭痛的其中一個地方, 就是 browser compatibility 的問題. 有很多時候, 在一個 browser 運作正常的 script, 在另一個 browser 會出現問題. 很多時進行開發的人都只專注於其中一個運行環境, 待完成後才去作較大規模的測試. 現時很多網站都大量使用 JavaScript, 很容易就會出現過千行的code. 這時候問題一出現就會很頭痛, 因為很多時候這類 browser compatibility 的問題並不會產生甚麼有用的錯誤訊息.舉個例子, 寫 PHP 的人很容易就習慣在建立 array 時在每個 item 後面都加上逗號, 例如是這樣:&lt;?php$myarr = array(    'item1',    'item2',    'item3',);?&gt;這樣做的原因, 是可以很方便的加、減或移動項目. 但是 JSON</summary><link rel='replies' type='application/atom+xml' href='http://geek-cafe-hk.blogspot.com/feeds/3883681004808725116/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://geek-cafe-hk.blogspot.com/2011/06/closure-compiler-debug-javascript.html#comment-form' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8035033083660504051/posts/default/3883681004808725116'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8035033083660504051/posts/default/3883681004808725116'/><link rel='alternate' type='text/html' href='http://geek-cafe-hk.blogspot.com/2011/06/closure-compiler-debug-javascript.html' title='借用 Closure Compiler 來 debug JavaScript'/><author><name>茄糞男</name><uri>http://www.blogger.com/profile/03341897835591864475</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_GWMqAoJtc_M/TDsZxm0yZJI/AAAAAAAANWY/k-qiPsMRXio/S220/blog2.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8035033083660504051.post-9004650496404567180</id><published>2011-03-31T23:24:00.004+08:00</published><updated>2011-03-31T23:35:30.305+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='CakePHP'/><category scheme='http://www.blogger.com/atom/ns#' term='PHP'/><title type='text'>快速開發 PHP web app - CakePHP</title><summary type='text'>製作 web app, 一般來說主要都是分兩個部份. 先是設定好 database 儲存資料, 然後就是製作介面, 令用家可以透過介面處理資料.這類介面一般提供資料儲存的四個主要工作功能: 建立, 查閱, 更新 以及 刪除, 亦即是所謂的 CRUD (create, read update delete).要是為每一個 web app 都重新寫一遍以上的功能, 會是一個又花時間又重覆的工序. 若果懂得利用 open source framwork 的話, 則事半功倍.CakePHP 所提供的, 是 MVC 加上 ORM 的模型. 其概念是從 Ruby on Rails 而來的.使用 CakePHP 的方法, 首先是在 Model 設定每一個 database table, 特別是 table 與 table 之間的關聯. 然後在相應的 Controller 中, 為每一個 View, </summary><link rel='replies' type='application/atom+xml' href='http://geek-cafe-hk.blogspot.com/feeds/9004650496404567180/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://geek-cafe-hk.blogspot.com/2011/03/php-web-app-cakephp.html#comment-form' title='2 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8035033083660504051/posts/default/9004650496404567180'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8035033083660504051/posts/default/9004650496404567180'/><link rel='alternate' type='text/html' href='http://geek-cafe-hk.blogspot.com/2011/03/php-web-app-cakephp.html' title='快速開發 PHP web app - CakePHP'/><author><name>茄糞男</name><uri>http://www.blogger.com/profile/03341897835591864475</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_GWMqAoJtc_M/TDsZxm0yZJI/AAAAAAAANWY/k-qiPsMRXio/S220/blog2.png'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8035033083660504051.post-5655225030533724475</id><published>2010-12-14T14:29:00.006+08:00</published><updated>2010-12-14T17:23:44.211+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JavaScript'/><category scheme='http://www.blogger.com/atom/ns#' term='HTML5 Audio'/><category scheme='http://www.blogger.com/atom/ns#' term='HTML5'/><title type='text'>在網頁中插入音樂</title><summary type='text'>一直以來, 要在網頁上播放音樂都是個令人頭痛的問題. 一個不負責任的 developer 可以很隨便的用一個 &lt;embed&gt; tag 來處理, 迫使讀者要在特定環境加特定的軟件才可以播放. [後補: 為免誤會, 我在此呼籲... 請各位必須避免在讀者不知情的情況下播放音樂. 例如是當進入頁面時自動播放音樂之類. 當你嚇到使用者的一刻就是他們離開的一刻.]&lt;embed&gt; 的最大問題, 是它並不是一個 HTML 4.01 的 tag. 不過這個 tag 在 HTML 5 重新出現, 結果就像是把不負責任的行為合理化一樣...&lt;embed&gt; 基本用途就是 embeded content, 亦即是瀏覽器會交由 plugin 去處理內容, 一般來說無法控制顯示的結果. 例如你 embed 的是一個 mp3 檔案的話, 用 IE 時可能會出現 Windows Media Player plugin,</summary><link rel='replies' type='application/atom+xml' href='http://geek-cafe-hk.blogspot.com/feeds/5655225030533724475/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://geek-cafe-hk.blogspot.com/2010/12/blog-post.html#comment-form' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8035033083660504051/posts/default/5655225030533724475'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8035033083660504051/posts/default/5655225030533724475'/><link rel='alternate' type='text/html' href='http://geek-cafe-hk.blogspot.com/2010/12/blog-post.html' title='在網頁中插入音樂'/><author><name>茄糞男</name><uri>http://www.blogger.com/profile/03341897835591864475</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_GWMqAoJtc_M/TDsZxm0yZJI/AAAAAAAANWY/k-qiPsMRXio/S220/blog2.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8035033083660504051.post-1188737188902413873</id><published>2010-12-04T22:09:00.006+08:00</published><updated>2010-12-04T23:12:51.359+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='GD2'/><category scheme='http://www.blogger.com/atom/ns#' term='Watermark'/><category scheme='http://www.blogger.com/atom/ns#' term='PHP'/><category scheme='http://www.blogger.com/atom/ns#' term='ImageMagick'/><title type='text'>利用 PHP 為圖片加上水印</title><summary type='text'>為保護自己網站的圖片, 很多時都會為圖片加上水印. 不過如果每一張都要手動加水印的話有時會很不方便.如果使用 PHP 的話, 其實可以利用 PHP 實時為圖片加上水印, 做法亦相當簡單. 而且還可以隨時轉換水印, 相當方便.使用 GD2 library現時一般的 PHP 設定都已經配備了 GD2 library. 利用 GD2 library, 就可以為相片加上水印. 方法是先載入要加上水印的圖片, 以及水印本身的圖片. 這裡假設圖片是 JPEG, 而水印則是 PNG.$image = imageCreateFromJpeg("image.jpg");$watermark = imageCreateFromPng("watermark.png");然後使用imageCopyMerge()這個 function, 就可以把水印加到圖片上. 假設水印是加在圖片右下角的話, 大概是這樣 (</summary><link rel='replies' type='application/atom+xml' href='http://geek-cafe-hk.blogspot.com/feeds/1188737188902413873/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://geek-cafe-hk.blogspot.com/2010/12/php.html#comment-form' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8035033083660504051/posts/default/1188737188902413873'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8035033083660504051/posts/default/1188737188902413873'/><link rel='alternate' type='text/html' href='http://geek-cafe-hk.blogspot.com/2010/12/php.html' title='利用 PHP 為圖片加上水印'/><author><name>茄糞男</name><uri>http://www.blogger.com/profile/03341897835591864475</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_GWMqAoJtc_M/TDsZxm0yZJI/AAAAAAAANWY/k-qiPsMRXio/S220/blog2.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8035033083660504051.post-8132299416096786328</id><published>2010-10-15T23:45:00.006+08:00</published><updated>2010-12-14T14:40:01.810+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JavaScript'/><category scheme='http://www.blogger.com/atom/ns#' term='HTML5'/><category scheme='http://www.blogger.com/atom/ns#' term='HTML5 Web Storage'/><title type='text'>HTML5 storage</title><summary type='text'>HTML5 的其中一個新功能是 Web Storage. 其中提供了 Local Storage 及 Session Storage 兩個新的 JavaScript object. 兩個儲存功能基本上與 Cookies 相似, 都是在本機以名+值(name &amp; value)的方式儲存資料. Local Storage 讓同一個網站存取資料, 而 Session Storage 則只容許在同一個瀏覽視窗中的同一網站存取資料.假設用戶同時開啟兩個視窗並瀏覽同一個網站. 利用 Local Storage 的話, 在其中一個視窗工作時儲存的資料, 可以在另一個視窗存取. 但如果利用 Session Storage 的話, 則在一個視窗的工作並不會影響到另一個視窗. 這是 Cookies 所不能做容易做到的.不過, HTML 5 的 Web storage 與 Cookie 的最大分別, </summary><link rel='replies' type='application/atom+xml' href='http://geek-cafe-hk.blogspot.com/feeds/8132299416096786328/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://geek-cafe-hk.blogspot.com/2010/10/html5-storage.html#comment-form' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8035033083660504051/posts/default/8132299416096786328'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8035033083660504051/posts/default/8132299416096786328'/><link rel='alternate' type='text/html' href='http://geek-cafe-hk.blogspot.com/2010/10/html5-storage.html' title='HTML5 storage'/><author><name>茄糞男</name><uri>http://www.blogger.com/profile/03341897835591864475</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_GWMqAoJtc_M/TDsZxm0yZJI/AAAAAAAANWY/k-qiPsMRXio/S220/blog2.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8035033083660504051.post-4836866274269845136</id><published>2010-08-26T15:46:00.003+08:00</published><updated>2010-08-26T15:51:04.667+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JavaScript'/><category scheme='http://www.blogger.com/atom/ns#' term='Deep linking'/><title type='text'>Deep linking</title><summary type='text'>在 AJAX 盛行的這個年代, 網頁內容往往都是利用 JavaScript 抓回來再顯示. 某程度上這樣可以提供一個更好的介面設計, 不過同一時間郤帶來另一問題: 如何讓讀者 bookmark 指定內容? 當讀者使用一個網址瀏覽一個網頁時, 如果網頁內容都是用 JavaScript (或者是 Flash) 更新, 網址不變的話, 讀者無法 bookmark 內容, 只能 boomark 首頁, 亦無法透過網址把內容分享至其他地方. Deep linking 的概念, 就是為網站的指定內容提供特定的網址, 好讓讀者可以利用這個網址去 bookmark 內容, 或和其他人分享. 這樣除了可以令網站更加 user friendly 之外, 同時亦為網站內容提供獨立網址, 方便自己把內容分享到不同地方, 間接擴闊了網站的宣傳渠道. Deep linking 的方法有很多, </summary><link rel='replies' type='application/atom+xml' href='http://geek-cafe-hk.blogspot.com/feeds/4836866274269845136/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://geek-cafe-hk.blogspot.com/2010/08/deep-linking.html#comment-form' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8035033083660504051/posts/default/4836866274269845136'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8035033083660504051/posts/default/4836866274269845136'/><link rel='alternate' type='text/html' href='http://geek-cafe-hk.blogspot.com/2010/08/deep-linking.html' title='Deep linking'/><author><name>茄糞男</name><uri>http://www.blogger.com/profile/03341897835591864475</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_GWMqAoJtc_M/TDsZxm0yZJI/AAAAAAAANWY/k-qiPsMRXio/S220/blog2.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8035033083660504051.post-1639175829084597091</id><published>2010-07-12T22:07:00.008+08:00</published><updated>2010-07-13T21:34:28.098+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JavaScript'/><title type='text'>Hello World @ JavaScript</title><summary type='text'>(本文首次刊於茄糞男Blog, 2010-06-24 14:24:34)這其實是做了兩年的 workshop, 都沒有認真考慮過的問題.JavaScript 的 Hello World 應該是怎樣才好呢?一直以來, 我都是用最初學到的一套, 就是用 document.write():&lt;script type="text/javascript"&gt;&lt;!-- document.write("Hello World!");// --&gt;&lt;/script&gt;這個Hello World 的最大問題, 就是在實際應用之中, 其實甚少會使用 document.write(). document.write() 大部份情況下只適用於當文件正在生成之時. 當文件已經顯示出來之後, 基乎都不會再用. 再者, 現時一般的做法, 都是等待文件載入後才開始執行 JavaScript (onload event), </summary><link rel='replies' type='application/atom+xml' href='http://geek-cafe-hk.blogspot.com/feeds/1639175829084597091/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://geek-cafe-hk.blogspot.com/2010/07/hello-world-javascript.html#comment-form' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8035033083660504051/posts/default/1639175829084597091'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8035033083660504051/posts/default/1639175829084597091'/><link rel='alternate' type='text/html' href='http://geek-cafe-hk.blogspot.com/2010/07/hello-world-javascript.html' title='Hello World @ JavaScript'/><author><name>茄糞男</name><uri>http://www.blogger.com/profile/03341897835591864475</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_GWMqAoJtc_M/TDsZxm0yZJI/AAAAAAAANWY/k-qiPsMRXio/S220/blog2.png'/></author><thr:total>0</thr:total></entry></feed>
