[Notes] Something you must know when fighting with IE7

Image Credit

全世界 Browsers 的使用率 (July 2012 ~ July 2013)

最近剛好有一些實戰機會可以和 IE7 來奮鬥,身為 FED 卻一直 skip 掉 IE7 好像不太好,有種沒有實戰過的感覺 xD … 現在想要把一些小細節記下來,希望能幫到想要和 IE7 奮戰的隊友們 xDD

δ 前情提要,如果是要解 IE6 的話 … 我只能請你自求多福。不過至少你能先叫做這個決定的豬腦去看一下微軟官方做的網站 IE6 Countdown,如果他發現自己做錯事的話,說不定問題就迎刃而解了呢 hahah。

奮戰流程:

  1. 如果你的作業系統不是 Windows 的話 (就算是 Windows 也是可以),那真的要先感謝一下佛心微軟放出來的 modern.IE ,因為你可以在上面找到各個作業系統上,各個虛擬化平台上內建好各個 IE 版本的虛擬硬碟。你就不用只為了測 IE 再來個什麼雙系統、三系統了,掛個 VirtualBox 就可以省下很多空間還有時間。( 因為我是用 128GB 的 SSD,所以空間有限,我個人的作法是把虛擬硬碟全部丟去行動硬碟上面,跑的很順也省下很多空間,可以參考一下)
  2. 在 fight with IE7 之前,先把戰力放在 Modern browsers。我特別去網路上找有關 browser 市佔率的各種資料,而資料整體上都是呈現出如本文一開始那張長條圖一樣的分佈。所以切記,時間就是金錢,特別是如果整個團隊就只有你這位 FED 的話,真的要先把事情都搞定後,再來打 Boss 呀。
  3. 終於要打 Boss 怪了,FED 們都知道(只有你家的 Boss 不知道) IE7 最強的攻擊技就是「完全沒有 Developer Tool」,這招真的強到讓人完全沒有還擊能力,因為通常 IE7 最大的問題就是 Layout 的不一致,尤其是對 IE7 完全沒有經驗的人來說特別如此,所以總是會很頻繁的手動調整 Layout。不過我找了一陣子後發現其實微軟有開發自己的 Developer Tool 給 IE7,只是並沒有內建在 IE7 裡面,而是需要自己手動下載來安裝,所以切記一定要先把你的 IE7 裝上 Developer Tool 呀。
  4. Let’s fight !!
  5. 特別開一個 IE7 fix,然後透過 Conditional Comments 來引入相關的 CSS / JS 檔案,這樣可以讓你原本的程式碼抽離於這些 hack 之外(我真的認為這些都是 dirty hack),所以不要 pollute 太多東西進去原本的 CSS / JS,這會造成維護上的困難也沒必要。
  6. 如果你使用到一些 CSS3 的東西像是 border-radius 或是 box-shadow 之類的屬性,記得搭配 CSS3Pie 來服用,通常可以解掉 90% 以上的 CSS3 問題,雖然好用但是要記得一些小事,就是有一些屬性只支援 shorthand version,請自行查閱一下 document 別寫得太開心到最後 Pie 看不懂就囧了。
  7. 通常 IE7 Layout 最大的問題是發生在 hasLayout 這個屬性上,根據 Sitepoint 這篇文章的解釋, 可以了解到這個是 IE 賦與元素的一個內部屬性,它的用處是「讓該元素本身及其孫元素(descendant)具有處理定位 (Positioning)及大小(sizing)的能力,而不是依賴於它的祖元素們(ancestors)」。而該文有列出幾個元素像是 img … 等。那為什麼會和這個屬性有關係?因為除了 IE 預設清單內的元素們具有這個屬性外,其他的元素是沒有這個屬性的,文章內有提到幾個常見的現象,像是「元素部分內容存在但是部分卻消失」或是「畫面只出現一半」。而要從 CSS 讓元素強制具有這個屬性有許多做法,最常見的做法就是設定一個 zoom: 1; 就可以了,這就是為什麼我們很常看到很多 3rd party libraries 在 CSS 中會加入這個東西的原因。不過這背後還有很多細節及一些奇特情況,可以參考微軟的這篇
  8. 如果你有使用 font-awesome 的話,請記得加入 font-awesome-ie7.min.css 的 hack,你會發現他都是在利用 zoom: 1; 來解 hasLayout,還有加入 innerHTML workaround 來解 IE7 不支援 pseudo element selector 的問題 xDDD
  9. 如果你有使用 bootstrap 的話(我是用 2.3),我發現如果用組合式 grid 來達成滿版的話(我這邊碰到的情況是 span6 + span6 或是 span4 + span8),整個 Layout 就會炸掉,所以要特別手動調整 width ,這邊要特別留意一下。
  10. 利用 zoom: 1;*display: inline; 來解原本被我們套用 display: inline-block; 的元素們(在 Modern browsers 我們用太習慣了,所以這個問題很多)。
  11. 如果你有用 <ul><li> 的話,不要用 list-style-image 來客製化他的樣式,因為如果有 position 上的需求,並沒有 CSS 可以直接控制這個值,可能會調到死,取而代之的你可以改用 background-imagebackground-position 搭配 padding 來手動 position,效果佳。
  12. … 未完待續

以上是和 IE7 奮鬥過的一些心路歷程,希望能幫到一些人,未來如果還有什麼有趣的狀況也會更新在這個清單內,Rock 😛

[Node.js] Difference between module.exports and exports

Image Credit

This simplified Chinese blog tells the details about the difference between module.exports and exports.

The most surprising part of the difference is that you can not use them together at the same time. (I know no one would use it in this way, because you have to make sure the coding style is the same anywhere.)

After testing, if you use these two ways to export modules, defined methods or properties in exports will be discarded directly and only export the ones defined in module.exports.

So I think the best practice here is to use module.exports instead of exports to define your stuffs.

Read More on : Here

[Javascript] performance issues when appending in DOM tree

Image Credit

According to John Resig’s blog, you can see that there is 2x-3x performance better when using fragments.

Take his code for example :

https://gist.github.com/EragonJ/6111312.js

If you use original append to append divs one by one, then you will see the blink on the screen especially when you are going to append a huge list. But, when using fragments, it is another kind of structure to hold these temporary divs and will be appended to the target all together at the same time.

So if one day you have to deal with massive DOM manipulation problems without 3rd party libraries’ help, remember to use it.

Cheeers 😛

Read More on : http://ejohn.org/blog/dom-documentfragments/

[Note] Missing part in Jade template

Image Credit

I have used Jade template for few projects and I really like it ! Its simplicity and indentation are key features to me compared with the other template engines. But recently, I have to build a website which can change layouts easily ( maybe by backend settings or routes ) to extend. But after trial and error and searching from the internet, I have concluded that it is one of important features lost in Jade.

Yeah, it is called “Dynamic Inheritance”.

According to this issue, you can find out that this is a known issue right now in Jade because of performance issues. (when writing this article, its version is 0.31.0) Because right now in the new design of Jade, you have to define your layout to extend in children pages, it is hard ( impossible ) to change layouts dynamically like what Twig or the other templates do.

So if you really want to do that right now in Jade, there is a workaround which you have to define two pages extending different layouts and trigger the right page in controller like this :

https://gist.github.com/EragonJ/5723087.js

That’s it, hope one day Jade can support this feature 😛

[Javascript] Build your own Trip with Trip.js

Image Credit

Demo : http://eragonj.github.io/Trip.js/
Repository : https://github.com/EragonJ/Trip.js

太久沒寫網誌了,所以想說來寫一篇最近比較值得記錄的事情,那就是 Trip.js

什麼是 Trip.js ? 一言以敝之就是「Trip.js is a useful plugin that can help you customize a tutorial trip easily. ( Based on jQuery )」,通常對於 landing page 或是一些需要做  step by step 指導的網站,都會需要這類型的 plugin 來幫助 developer 快速上手,做出需要的效果 ,而剛好之前在公司的時候有類似的需求,所以我就在其他時間自己先行開發了 Trip.js 的初始版,然後分享在網路上。

就目前看來感覺效果還蠻出眾的(在 hackernews & github 上都有一些回響),雖然市面上還有很多類似的 plugin,但是東西是自己寫的那種感覺就是很不一樣,有興趣的 developer 不妨參考一下吧 😛

[Research] Realtime 時代對 UX 造成的衝擊

P.S. 文章刊載於  L5L

Image Credit

Realtime 又名即時性,在這個資訊爆炸的時代尤其重要。為什麼會這麼說呢?因為海量資訊的產生,使得人們對於冗長的事物失去了耐心,取而代之的是「快且精準」的需求,而這個層面不僅僅只於閱讀,更衍伸到 UX( User Experience 又稱使用者體驗 )的領域去。

其中最經典的例子,莫過於 Mike Krieger (Co-Founder of Instagram)對於 Instagram mobile app 上傳流程的設計:

投影片連結

這個改變看似簡單,但其背後卻存在著更多細節需要實作,在做進一步討論之前,我們就先估且稱這個改變叫做「前端欺騙(Front-End Cheating)」吧。

以剛剛的流程為例,在後端的設計就可能需要額外設計一個 Image Pool 來暫存這些無人認領的照片孤兒,直到該使用者「完成了整個上傳流程」才會把這張照片指定給他。而對前端來說,就必須捨棄原本的流程,從「拍照→濾鏡→填寫資訊→上傳→結束」改變成「拍照→濾鏡→上傳→填寫資訊→使用一個 identifier 告訴 backend 更新照片資訊→結束」。

不過,以上只是最理想的假設,因為現實生活中還多了許多變數,特別是在 3G 網路的不穩定性還有 app 與 desktop program 設計上的差異,使得上傳的流程不如以往的順利及穩定,造成許多中斷及錯誤的可能,所以在 Error Handling 的部分還要做額外的處理。

對 Instagram 來說,它還需要再設想幾個情境:

  1. 使用者已經上傳完照片,卻在最後一個 Moment 按下 Cancel 鍵取消了所有動作,那該怎麼辦?
  2. 當「前端欺騙」後,卻從 backend 發現先前的上傳失敗,那該怎麼辦?

以情境 1 為例,舊流程是完全不會有這個問題(因為根本沒有辦法讓你中途取消),但是在新流程卻發生了,不過解法也很簡單,就是透過 identifier 告訴後端,從 Image Pool 幹掉這張照片就好了。

而情境 2 就比較麻煩,雖然新舊流程都需要處理上傳失敗的 UI 設計,但是對新流程來說,我們還要特別處理掉原本因為「前端欺騙」所留下的 UI ,又多了一個要考慮的細節。

除了 Instagram 這個經典上傳照片的例子外,還有一個更常看到的就是 Facebook Like。

對 Facebook 來說,他們處理的是更海量的資料(從別人文章得到的數據是一天約 27 億個 Like),所以更需要這種「前端欺騙」的動作來滿足使用者,而 Like 就是一個很好的例子。對使用者來說,Like 是一種 … 該怎麼說,是一種食之無味卻又棄之可惜的東西,他的出現讓資料庫又塞了更多無用的資訊(27 億個 Like per day ),但是卻又可以為不想發言的使用者傳達「我有看過了」、「很棒」…  的意義。

這種類型的資料特別適合透過「前端欺騙」的方式來處理,怎麼說呢?因為你可能只是當下想表示一種「認同」,但是資料的正確與否你就不會特別在意,舉 Michael Jackson 在 Facebook 上隨便一則 Post ,就會出現像是「You and 177,449 others like this.」的字眼,但是你真的會很在意 others 是哪些人嗎?通常不會,因為你真正在意的,通常是「你」和「你朋友」而已,其他陌生人 Like 與否相對就沒有這麼重要了。如果真的這麼重要,Facebook 也有做分頁載入(以 Infinite Scroll 的方式實作)的機制,你頂多看前一兩百個陌生臉孔也就不想再看下去了,遑論是那第 177,447 人呢?

所以就我個人的觀點來說,Realtime 意指的「即時」並不是資料傳輸的即時,而是對於 UX 的即時反饋。而文章標題所謂的衝擊,則是人們對於這一個領域的重視,一個被眾人遺忘已久的枝微末節。

[Javascript] Some good/bad parts learned from Chrome Extension

Image Credit

Just update my FBBK from version 1.0 to 1.2.1 and think there are some nice features/designs to be noted about Chrome extension.

  1. chrome.storage API

    When using manifest 1, we have to set up a background page  as middleware to communicate between content scripts and localStorage ( used to store users’ selected options ) because the localStorage used in content scripts will be referred to the page localStorage instead of extension localStorage.In this way, developers have to make build up a fake background page to transfer data. But this problem has been solved by chrome.storage API. With this API, we can easily set/get data for content scripts without the help of background page.Better than that, this API can also synchronize data from local to the cloud to solve problems when users using different computers. The most awesome part is that the API would automatically fallback to store data in local if the internet connection breaks !
  2. chrome.i18n API

    It is really important to i18n your extensions/apps if you want to reach the global market ( users ). For FBBK 1.2.0+, I just implemented two locales ( en / zh ). I really like the design that Chrome can automatically detect the right locale to be used  and even falls back to default locale.This API is really smart enough for basic projects but can’t meet more complicated needs. Take FBBK for example, There are many models with i18n needs ( to describe models’ usage, intro … blah ). Because Chrome doesn’t support a good way for me to get the current locale ( can use predefined variable like @@ui_locale in CSS but not in JS  ) , I have to proxy the models descriptions to  use chrome.i18n.getMessage() to get the right locale and match the right message.json ( see the above figure ).

    This is how I do in FBBK :

    https://gist.github.com/4259985.js?file=gistfile1.js

    If you have better ideas to extract models with i18n json, plz comment to let me know !

That’s it ! Have fun on developing chrome extension 😉

[Hack] 2012 – Node.js Knockout

Image Credit

這是我第一次參加 Hackathon,雖然平常也沒什麼特別在寫 Node.js,頂多只有用 Express.js 試著架一些小東西來玩玩而已,不過還是憑著一股衝勁和 @bu 以 hahahaha ( hax4 ) 的名義參賽。說真的,我們也只有特別約出來吃一次飯,然後討論看看有什麼有趣的東西可以做,就在一陣東刪西減之後得到了一個明確的主題,那就是要做一個可以「動態捕捉使用者在網站上的各種行為」的外掛,同時還可以把資料記錄下來再做一個重播的動作,讓 Host 知道用戶在使用網站時的各種行為(目前是記錄 Click 和 mousemove 兩種)。

而我們的作品就是 Capturer !

很開心的就是這個 Idea 被大家所認同,所以最後得到第二名的成績!這一切都要感謝強者我隊友強大的後端實作能力,我只負責前端的行為記錄、呈現還有和後端溝通,還有研究 nodejitsu deploy 的一些細節而已,整個就是微不足道的小廢角。

廢話不多說,我真正想講的是這次 Hackathon 教我的東西:

很多時候,我們都眼高手低並空談著許多名為夢想的東西,同時卻又因為現實的工作的壓迫壓力而抹滅掉熱情,所以這種時候透過比賽這種強制手段來逼自己成長與學習了,一個兩天的比賽換來一個作品的 prototype ,同時也測試著這個團隊的合作能力,整個就是 Target-driven(動機導向) 的開發模式呀。

最後,Capturer 的使用方式還有介紹就麻煩到 神人的 Blog 去看啦,我們會努力在明年讓這個系統上線的,加油 !!

 

[Notes] MOPCON 2012

mopcon

剛從 MOPCON  回來,想說趁著對幾個議題還有些印象的時候記錄一下當時做的筆記:

  1. Registrano by hlb
    • 自訂表單 
      滿足使用者客製化的需求,這個困難點應該是在於如何把「使用者自訂的表單」儲存在現有的資料庫結構之下,應該要設計出一個特定(或統一)的格式(類似 JSON or ? )來達到真正的「客製化」。
    • 超賣
      票券類型的服務大多時候都會有名額上的限制,所以要避免超賣(Oversell )的問題。關鍵字:Table Lock, Row Lock, Unique Sequential Number
  2. Firefox OS by Cervantes
    • Gaia
      The UI for Boot to Gecko ( B2G ) ,前端工程師可以參考他們的 UI 設計細節
    • 備註
      給予 Web App 使用更進階 API 的權限來存取 Device 底層的資訊(Web App can work like Native App now )
  3. pjax by XDite
    • What is pjax
      HTML5 pushState +  ajax
    • 備註
      • 解決 ajax 動態載入但是無法 prev / next 的問題(因為透過 ajax 方式載入的內容是沒有辦法被記錄在 History 裡面的)
      • 解決 Twitter 以前透過 #! hashchange 的方式來達成 prev / next  但是不夠 SEO Friendly 的問題
      • jQuery pjax 可以依 browser 支援程度來做到相對應的 fallback,堪稱神器。
  4. 行動網路上 API 設計準則 by gslin
    • 前提
      行動網路上的先天限制,就是很容易斷線、不穩、電量不足、速度慢。
    • API redesign
      因為 device 的差異所以要調整 API 以降低 request 次數。實作則是可以透過 extra parameters 把額外的 API 做一個整合,雖然 dirty 但是可以省 request。要注意的部份有:透過某種 Serial 的值讓 Server Side 知道該 device 的某個一次性行為曾經執行過,以「確保」不會被重覆執行。
    • Atomic API
      對 mobile 的 API 設計時,要盡量以 Atomic 的方式設計,讓很多關聯性的動作 ( 例如開專輯、設定歌、 …  ) 一次做完,不要分開做。這個 Atomic 的思惟有幾個層面,就 Server Side 來說,只要回傳「必要的」資料就好,同時在傳遞資料前要先做一層壓縮以加快傳輸的速度,「即使」 Client Side 要多花 effort 來做解壓的動作,但是總比維持在一個「不穩定」的連線上面瘋狂 retry 好,因為總的來說,其相對所花的時間也會比較少。(請參考前提)

以上就是這次活動讓我收獲比較多的部份,也歡迎留下你的看法 😉

[Notes] CSS Cross-Country

Image Credit

最近為了讓自己保持繼續學習的動機,所以就很衝動的花了 25 USD 買了一個月份的 Code School 資格,而首當其衝的課程就是身為 Front-End 不能不了解的 CSS。

雖然不是說完全不了解 CSS,但是我很想知道如果是付費教學的話,它會怎麼樣「教」CSS 這種很難以捉摸的東西?(你說 CSS 簡單它還真的可以很簡單,但是在這著重視覺特效還有正在經歷瀏覽器大戰的世界,CSS 還是真的可以他媽的難。)

最後証實沒有白花錢,因為這個教材也直接切入很多 CSS 技巧的核心,都是我在外面亂撞好幾十次得到的慘痛教訓,除此之外也有一些我沒有留意過的細節,看完整個教材加上 Challenge 的練習之後整個就是對 CSS 的掌握更多了一點,以下就是我由 Level 1 ~ Level 8 覺得很重要的筆記:

  1. Non-Conflicting properties will be combined
  2. 浮動的元素如果超過了 parent 的寬就會被擠到下一個「可能的」位置,這個時候如果元素之間的高度不同,就會影響被擺放的位置(可以想像一下 Pinterest 的 Layout ,他不是依照由左到右的順序擺放格子,而是會去尋找「上一層高度最小」的位置去插入來達到不規則的瀑布流,它的演算法下次再來開新文章分享。)
  3. 同時有多個 float : left | right; 的元素「會依 DOM 的先後順序」來決定誰在最左或最右邊
  4. 如果子元素有 float 的話,要記得在 parent 設定 clearfix (參考 Bootstrap 很有名的 clearfix 方法,我在面試 T 公司的時候就是用這個方法來解決 floating 的問題)
  5. CSS 的 Specificity 計算( 0, 0, 0, 0 → inline style, # of ID selectors, # of class selectors, # of element selectors )
  6. 不要用 !important 讓未來的自己後悔 …
  7. Box Model 還有 width / height 的計算(因為和我們直覺想的完全不一樣,所以要留意。)
  8. 父元素 postion : relative 搭配子元素 position : absolute 是一個超重要也常用的排版技巧
  9. Z-index 要發揮效用的前提是該元素一定要被 positioned
  10. CSS property shorthands
  11. Block element / Inline element / Inline-Block element 的差異
  12. 置中 Block element 的方法 – margin : 0 auto;
  13. 置中 Inline / Inline-Block element 的方法 – text-align : center;
  14. Collapsing margins
  15. Content 用的 images 和 裝飾 Layout 用的 images 要用不同的形式呈現,前者建議是以 inline images 的形式,而後者建議是用 background images 的形式
  16. Image Crop with overflow hack
  17. 增加「說明用的文字」在要被 image 替換的元素上,利用 text-indent : -99999px 的 hack
  18. CSS Sprites 好處:減少和 Server 的溝通次數、避免 :hover 等事件出現閃圖的情況
  19. 善用 Pseudo Class (有些真的很強大 … )

以上,特別筆記一下!