跳到主要內容

發表文章

目前顯示的是 2013的文章

CSS 樣式覆蓋規則

參考連結(2018更新):CSS Specificity

在複雜的頁面裡,HTML元素套用到互相衝突的CSS指定的情形並不少見
本篇文章會說明元素的CSS指定來源以及設定的優先順序
寫出正確、有效率的CSS對於網頁表現絕對有很大的幫助

CSS套用規則有以下重點:

1.CSS樣式的繼承 部分CSS指定會讓子代元素繼承相同指定,例如 font-size、font-family等
當祖先之間的指定並不相同時,會以較接近的祖先的樣式為準

實務上常見指定font CSS給body,讓整個頁面都以相同的字體大小、風格呈現
不過當某個區塊被指定了不同的font CSS,其子代元素呈現的CSS就會是該區塊的CSS指定

2.直接指定給元素的CSS樣式 直接指定的CSS套用優先度高於繼承的
其實跟上一點有關,離自己越近的規則的優先度越高,當然指定給自己的就是最優先囉

3.直接指定的樣式發生衝突時,以指定方式的加權值高者優先
CSS selectors                  權值

Type selectors                     1

Class selectors                   10

ID selectors                     100

Descendant selectors
Adjacent sibling selectors
Child selectors 等          1000

Pseudo element                   1

Pseudo classes                  10

CSS 基礎與選擇器使用一文中,有提到越多層次的選擇器指定會降低效率
不過當頁面複雜度高時,有時候也只能多套用選擇器來提升指定加權值

4.當CSS樣式加權值相同時,後指定者優先套用

Ajax跨網域議題 - 透過POST方法送出資料

對於跨網域議題有所不懂或是想知道如何用GET方式處理,可以參考Ajax跨網域議題 - 使用JSONP取得資料
當我們在運用各種服務提供的RESTFUL API 時,資料傳遞的方式就相當重要
JSONP的處理只能透過GET的方式傳遞
扣除在Cross Domain所不允許的DELETE、AUTH兩種傳遞方式外
實際上我們還是可以用寄送表單的方式送出POST請求,只要透過一點想法的變換就可以
GitHub檔案目錄

Tree Structure 實作

雖然說Tree也還算是常用到的結構
不過大概是因為它的設計彈性太高,大部分的程式語言似乎都沒有高完成度的容器實作
有時候要依自己需求調整還是只能自己刻一個
這個範例用JavaScript刻一個自用版,應該還有地方可以改進就是...
當然如果不考慮就瀏覽器的相容性,也許用 document.implementation.createDocument 可以少一些工
另外JSON等結構也可以模仿一部份的操作
總而言之就是如果不是真的確定非這個結構不行,是不必要自己刻輪子來用
Java等程式語言用的版本也可以參考這個的概念來改
GitHub檔案目錄

自助旅行 Day6(2013/08/23) 上野 & Day7(2013/08/24) 回台灣

這一天一大早就先去明治神宮
明治神宮的開放時間基本上是日出開門、日落關門
所以這天一早就打定逛完明治神宮後,再回旅館吃早餐、check out
我們去的這個禮拜都可以在地鐵站看到明治神宮的元氣祭的宣傳海報
只可惜時間帶是24、25日,24日就要前往機場,所以也沒時間去逛,沒逛到祭典還是可惜了些

明治神宮裡有龐大的森林,要逛完花的時間也不少
入口處的鳥居,用的樹可是來自台灣丹大山的扁柏
目前明治神宮的鳥居用的建材都來自台灣,在異國看到台灣的樹總感覺格外親切

自助旅行 Day5(2013/08/22) 神樂坂→新宿

回東京後的行程是接著往神樂坂去 其實會排神樂坂是因為一開始的行程預定先到早稻田大學參觀,所以挑了個在早稻田附近的區域參觀 雖然之後沒打算到早稻田了,還是保持神樂坂的行程 查神樂坂的景點主要有東京大神社、毘沙門天善國寺和赤城神社 東京大神社是伊勢神宮的分靈,不過這次我們並沒有到那邊
到旅館放行李後,先前往神樂坂的赤城神社 赤城神社的環境清幽,環繞著典雅的氛圍

自助旅行 Day4(2013/08/21) 鎌倉→江之島

湘南地區給人的印象就是陽光和大海
來這裡、或者說來神奈川的行程才是我私心安排的行程(笑)
這裡是不少日劇、動漫的主要場景
以日劇來說, '12年的[倒數第二次戀愛(最後から二番目の恋)]的主要地點就是湘南,雖然我沒看
動漫的話包含了著名的灌籃高手(Slam Dunk)ELFEN LIEDTARI TARIうた∽かた、湘南純愛組等
這次我是以 Memories Off(メモオフ) 的 fan 的身分前來朝聖的(笑)



上圖是鎌倉車站(鎌倉駅)所展示的地區特色土產
鎌倉在過去曾經是日本的首都,所以也有不少地方還有著古都風情,許多有歷史的神社、廟宇也在這裡
湘南的海岸是相當著名的衝浪盛行地
江之島是相當著名的觀光勝地,島上的貓的數量很多,也是日本十大貓島之一
大概是因為日本修驗道始祖役小角曾經住過這裡,島上的神社也是沒怎麼在其他地方看過的龍宮信仰
光上述就可以想見這裡可以逛的地方非常多
這一天也走了相當久的路,可能單純以一天的量來說還OK
不過因為已經連續走了幾天路,我們這一天走起來還滿累的
算是在自助旅行的行程規劃上學了一課

自助旅行 Day3(2013/08/20) 橫濱

第三天我們往神奈川縣的首府 横浜 出發
横浜同時也是日本的第二大都市,很有魅力的城市
如同日本其他地區的觀光引導做得很好,横浜市政府的觀光網站也很值得一看
要看完横浜的主要景點大概要有兩天是比較充裕
我們挑了一些比較感興趣的行程安排了一天,挑選的都是在地方私鐵港區未來線(みなとみらい)的周圍
先說我們一開始就沒考慮中華街了XD,中華街裡有關帝廟、媽祖廟等華人信仰寺廟
不過聽說也不是太有特色,街區裡的中華料理價格相較之下較高,當然也不比在台灣吃到的道地
雖然有路過,不過沒特地往裡面繞

當我們拖著行李移動換乘到港區未來線時就感受到不太一樣的氣氛
這裡的車站裡會撥放海鷗的叫聲的音樂,車站建築的裝潢風格也和東京的不同,一下電車就像來到海邊
横浜的格局是大又漂亮,路面的整潔程度也很好
雖然是第二大都市,不過路面的人潮意外地沒有很多,散發出較為輕鬆的氣息,我滿喜歡這座城市

自助旅行 Day2(2013/08/19) 築地→自由之丘→秋葉原→東京鐵塔

這天早上原始的預定是五點從旅館出發,搭最早班的地鐵到築地去吃最有名的寿司大
不過預定就是用來打破的...囧 大概是前一天老爸老媽是開夜車到機場的關係,所以起床時間就延遲 因為一開始就預期如果晚起床的話寿司大的隊伍應該就排到天際去了 半放棄的狀態下就放緩了早上的節奏 到築地的時間差不多是早上7點左右,附上一張沿途經過的築地本願寺照片

自助旅行 Day1(2013/08/18) 成田機場→東大→晴空塔

自助旅行的第一天當然是從到機場準備登機開始囉
先說說到機場的交通方式吧~
因為酷航的班機起飛時間較早,如果不想提前到機場等候,除了自行開車外,也可以考慮搭乘計程車
另外大部分的信用卡都會有送機服務的條款,有信用卡的人也不妨看看自己是否符合銀行設定的條件
我最後選擇前一天晚上就先到桃園機場跟友人K氏會合,過夜等check in

從台北到桃園機場最便宜的方案是大有巴士,90元的費用比國光號的160元或高鐵都省的多
大有巴士的發車地點是台北車站隔壁的轉運站,跟國光號同樣地點
雖然車程預計是1.5個小時,不過我搭的最後一班23:00的班次只花了1個小時就到桃機了
想來在夜間車流量不多的情況下,搭高鐵也不會比搭客運快多少,可以多考慮客運節省費用

到機場後就準備睡覺等酷航開櫃啦
先提醒最好著購保暖的衣服,否則就會跟我一樣被機場的冷氣吹到睡不著
睡不著的時候看的到一些比較難得的景象
夜間沒有人使用的手扶梯是停止狀態喔...XD



















第一次自助旅行 東京行前規劃Review

上個月進行了人生第一次的自助旅行
這個旅行花了我滿多時間規劃、準備
也因為是出社會後的第一次旅行,所以也帶著爸媽一起到東京玩
當然考慮到整團只有我一個年輕人的話,總擔心玩得不盡興(這個是說我XD)
另一方面也是想找個人一起煩惱,哈!所以找了跟我爸媽也很熟的友人K氏同行
整個旅程算是非常順利,天氣也都不錯,也謝謝K氏的幫忙,玩得非常愉快
打從一開始就打算回來後要寫分享文,不過回台灣後一直整理東西就花了不少時間
現在覺得不寫實在不行了,不然越拖越懶得寫XD

整個旅行的規劃流程大致如下
看到機票優惠後,衝動定下去的時間大概是2月底
所以4月初到6月中後先跟K氏完成了大部份的規劃
直到出發前一個月開始核對現況跟資料收集時的落差,也關注現有的優惠等消息

接著稍微回顧並修正準備規劃

[轉載] 手機端DataURI比外鏈資源慢6倍

原文連結:前端觀察

網頁中使用DataURI會多消耗53%左右的CPU資源,記憶體多出4倍左右,耗時平均高出24.6倍
mobify最近做了一系列手機端的測試,測試顯示平均下來,DataURI要比簡單的外鏈資源要慢6倍

範例 - JSP 使用Gmail為SMTP server

此範例單純寄信,不夾帶檔案
另外可能是google本身有GAE(google app engine)服務
Gmail不適合當作商業用的mail server
除了安全認證外,本身也有寄信上限100封 / per day
在Server上也可能有認證交換阻擋之類的限制
我在自己的電腦上使用沒問題,但也曾經在Linux的Server上碰到認證的Exception
如果要找商業使用的mail server最好還是另尋他途(例如:sendGrid)

JavaScript stack trace 使用方式

觀察函式的呼叫過程(堆疊過程)一直是程式語言的除錯方法之一
相較於後端用的語言大多能透過console印出出錯部分的code和stack
JavaScript碰到錯誤時的方式是立刻block並提示出錯的code,但不提供stack
部分瀏覽器的developer tool提供了程式碼的stack觀察設定,可自行查閱資料(例如:chrome)

如果要透過JavaScript code執行,則在想觀察的部分加入以下代碼:
var e = new Error();
console.log(e.stack);

如此就能得知觀察處的程式碼是如何被呼叫

增加 Putty 的緩衝容量

Putty 是常用來對Linux下指令的軟體
但畢竟作為Server用的Linux上跑的東西、訊息繁多
很容易超過預設的buffer size,而看不到那些先被送出的資料


每次進入Putty的介面都是先到它的 <session> category
這裡可以儲存常用的連線
沒有使用其他連線的話就是處於預設狀態


接著切到<Window> category 將Lines of scrollback調高
預設是200,範例是直接調高到20000
之後再回 <session> category 儲存後,Putty的預設buffer就調高了

JavaEE Session、Cookie處理

last update:2013/6

一般的網頁連線過程裡,server端與client端的互動就像丟球遊戲一般
由client端丟球(連線)到server端,server端再根據過來的資訊把球丟給(回傳資訊)client端
而每一次的連線行為都是獨立的
server端專注接球並把球傳回去,並不會注意是誰把球丟過來

如果過程中有需求要持續辨識使用者的身分,則會透過Cookie、Session兩種機制來辨識
Cookie是將資訊記錄在client端,並連線時將訊息一併傳遞給server端
用比喻來形容就是在球上面簽名,server端接到球後就會知道是誰把球丟過來
Session則是將資訊存放在server端的記憶體中,並依此辨識
比喻是接球的server端用大腦記著每一個丟球給他的人

當然以上比喻對於細節也許不是那麼符合
而當系統對連線的辨識需求較多,或是即時性的要求較高(例如:twitter、線上聊天等系統)
使用Cookie、Session機制就不是那麼有效率了
包含HTML5也提出WebSocket機制來處理這類需求,而過去也有幾種標準作法
介紹可以參考JosephJ大的文章 - Browser 與 Server 持續同步的作法介紹

遭網路購物詐欺的對應

對應過程來自我的經驗 orz
雖然離處理結束也過了一段時間,不過最近比較忙,沒什麼空寫技術文章,所以拿出來經驗分享
首先是發現遭詐騙後,得立刻報案,並檢舉該帳戶(如果是匯款) 報案時注意,如果縣市政府有網路報案的機制,建議最好透過網路報案處理 網路報案完後,他會通知你還是得到受理的警局完成手續 但網路報案最大的好處是讓警方無法吃案,畢竟這是不容易偵破,影響層面又不大的案子 而且警察杯杯的打字速度大多很慢,先打好一些資料也會加速處理速度
接著是資料的保存,包含購物平台的資料及匯款資料得盡量備份 以我的情況是在報案快一年後才有後續通知 也因為一開始沒想過會偵破,所以資料備份不齊在後續處理有點吃虧,詳細情形後述 很多網購平台開放公開查詢的資料只限半年內(露天購物是如此),之後要再收集當時資料會很麻煩

使用Google Closure壓縮Javascript檔案

Google Closure是滿常被使用的開源JavaScript壓縮器
GCL的GitHub page:https://github.com/google/closure-compiler
GCL線上版本:http://closure-compiler.appspot.com/home

其餘主流的壓縮器介紹可以看談以壓縮、cache機制加速網路應用
以壓縮比例來說,GCL會較YUI compressor略好一些
這是因為兩者的機制有所不同

兩種壓縮器都提供3種層級的壓縮
最簡單的壓縮就是移除JavaScript檔案中的空白、換行符號
接著是預設的基本壓縮
除了不會變動全域變數、函式外,區域變數會重新命名以進一步減少檔案大小,一部分的多餘程式也會被移除
進階壓縮才是兩者的差異,YUI compressor純粹解譯JavaScript的程式碼文字
而Google Closure是compiler,會重新編譯成新的JavaScript code
也因為如此,GCL對於程式碼的要求比較嚴格,也是有些人會反映編譯時容易報錯
就我個人來看,設計師要求自己的code能通過JSHint、JSLint是基本條件,所以不覺得是問題

判斷IE版本的簡單方法

微軟從IE8開始,在IE裡實作了一個物件 document.documentMode 紀錄了IE的版號
例如在IE8裡為 8,IE9裡為 9,依此類推 如果使用開發者工具調整回IE7模式會取得7,當然如果是原生的IE7及以下會拿到undefined 另外注意如果觸發了舊IE的Quirks Mode(也就是IE10的IE5 Quirks),則會取得5
以現在的IE版本分布來說,IE7已經占不到1%,是可以忽略的數字 而微軟也開始強制Win7從 IE9 升級到 IE10 剩下最麻煩的XP的IE8....,也因為如此document.documentMode現在是可以倚賴的判斷工具 判斷 document.documentMode <= 8 就可以區隔新舊IE了

另外在 user agent 中也有方式可以辨識
可以參考 從user agent辨識新版 IE (IE11)

Mobile 開發可以多利用的HTML5新事件

1.判斷使用者是否在線上有更明確、簡單的事件可用
wwindow.addEventListener("online", function() {
  console.log("online.");
});

window.addEventListener("offline", function() {
  console.log("offline.");
});

2.多用touch event 取代滑鼠 event,特別是 touchstart 跟 onclick 的反應時間有些差距
3.觸碰筆跡的新事件
onpointerdown, onpointerup, onpointermove, onpointerover,
onpointerout, onpointerenter, onpointerleave.

4.調整為全螢幕顯示
過去常用的作法
window.scrollTo(0,1);

可以使用的新方法
[element].requestFullscreen();
[element].currentFullScreenElement();
document.cancelFullscreen();
document.fullscreenEnabled();
document.isFullScreen();

5.瀏覽器的事件處理流程如下圖,Mobile開發可以多注意關於載入順序的部分

找回遺失的Android手機

再一天感謝科技的力量 今天到了公司才發現手機不再身上
不過一直想不起來到底有沒有帶出門 = =|||
回家後才確定手機掉了 orz

雖然查遍網路上的資料發現滿多軟體有做手機遺失相關的
不過最後是靠著救世神器Google定位找回來
畢竟再怎麼說衛星定位也沒有其他家做得更好了吧
查看記錄才發現原來今天我的手機已經搭著公車做了好幾趟的循環旅行

最後靠著 攔下公車 > 殺上去 > 撥打電話 > 找到手機 > 殺下車 精簡的連續動作
終於讓他又回來QQ
分享一下給大家知道手機掉了要怎麼找回來Orz

追記(2013/10):
現在Google新增加了Android 裝置管理員這項服務
只要手機的系統是Android 2.2以上就能支援,整合了包含定位等服務,找手機更方便

CSS 基礎與選擇器使用

參考文章:如何撰寫有效率的CSS選擇器(CSS Selector)
那些 CSS 偽元素可以幫你做的 10 個效果

CSS用來制定HTML元素的顯示外觀
在Web上的功能大致可區分為 HTML - 資料集合、JavaScript - 操作控制、CSS - 外觀指定
跟JavaScript一樣,CSS能以內部撰寫或引入外部連結使用
內部撰寫會需要在<head>元素裡撰寫<style>標籤,然後把CSS的內容寫在裡面
如:
<style>
    p { font-size:16px; }
</style>

你可能會發現把<style>標籤放到<body>裡也可以執行,但實務上非常不建議如此
原因是如果先讓瀏覽器讀取CSS,你可以快速地看到CSS的效果套用在HTML上
另一個原因則是每當瀏覽器在<body>裡讀取到<style>標籤後就會重新繪製畫面,以確保符合CSS要求
重新繪製畫面對效能上會有很大的影響

外部連結則需要在<head>元素裡撰寫<link>標籤
href屬性指定了CSS檔的位置,rel屬性則標示了檔案和頁面的關係,如下示範:
<link rel=stylesheet href="css/base.css" />

CSS的語法結構是選取器 { 屬性:設定值;} ,註解形式則為 /* here */
以 p { font-size:16px; } 為例,這行指定了所有的p元素都必須套用16px的字體大小設定

JavaScript - 使用Regular Expression讓 replace() 做到 replace all

如同一般程式語言的replace() method一樣
JavaScript的replace()也只會取代第一個符合的字串
如果要做到 replaceAll() 的效果必須透過正規表示法來指定全域,如:
str.replace(new RegExp("&#44;","gm"),",");

RegExp的第二個參數g、m分別下了兩種搜尋規則
g - global match   m - working over multiple lines
這裡還能指定一種沒用在上述例子的 i - ignore case
設定完RegExp的搜尋規則便能達到目的

LZW 壓縮演算法

LZW衍生自LZ77演算法,為一方便實作且受到廣泛運用的壓縮演算法
在較早期因專利保護的關係,另一個現在也常用的演算法GZip被提出來取代LZW的使用
不過現在LZW在世界各國的專利大約都在2003、2004年左右過期

LZW主要運用在文字及影像的壓縮處理上
他的實作方式是建立一個字典來記錄出現過的文字(字元)
例如:[AA: 258, AAA: 270, AAB: 264, AB: 256 ....]
字典在壓縮完後就被拋棄,解壓縮時則會在運算時依相同規則再建立一本字典
所以當重複的文字或字元較多時會有比較好的效率,反之則有可能幾乎沒效果
這個特性同樣適用在影像上,對於具有大範圍相同顏色的影像有較好的效果
這個演算法的特色是實現簡單,但因為不會對內容作分析,所以不見得是壓縮比最好的演算法
以下為JavaScript的LZW演算法實作

基礎演算法想法

演算法簡單來說就是處理問題的方法
問題必須限定於能在有限次數內得出有效解
想辦法提升解答的效率就是演算法的精神
針對各種需求例如搜尋、排序等,分別有對其最有效率的演算法

而各種演算法的設計原則大概可基於以下幾個概念

HTML 元素的 tabindex 屬性

在網頁上填寫資料時,常用 Tab 鍵來切換要輸入的欄位
而如果填寫資料有特定的順序,或切換欄位的順序需要調整
可以設定元素的 tabindex 屬性來滿足需求

<input type="text" tabindex="1">
<input type="text" tabindex="3">
<input type="text" tabindex="2">

大家可以試試上面的程式碼(線上範例)
按Tab鍵切換輸入的欄位會依照 tabindex 的大小順序變化
而一份HTML文件中每個 tabindex 都只能有一個元素擁有
如果有複數的元素指定了相同的 tabindex ,則只有最後指定的元素的 tabindex 會成立
在JavaScript中要設定此屬性使用 element.tabIndex

JavaScript 解析網址列字串取得location物件參數

參考文章:Parsing URLs with the DOM!

Javascript中的全域物件 location 中帶有許多方便的參數,讓我們能方便取用
例如:
location.pathname 可以取得當前URL的路徑字串
location.hostname 可以取得當前URL的主網域路徑字串
另外location物件還解析了更多URL的特性

如果要讓網址列字串一樣可以解析出這些參數,需要一點小技巧,透過 <a> 元素來實現

var a = document.createElement('a');
a.href = "http://www.google.com.tw/reader/view/#overview-page";

a.protocol     //"http:"
a.hash           //"#overview-page"
a.hostname    //"www.google.com.tw"
a.pathname   //"/reader/view/"

偵測瀏覽器版本

JavaScript的全域變數 navigator.userAgent 是現在判斷瀏覽器版本的依據
它最一開始是被瀏覽器用來標示支援的標準
隨著瀏覽器的演化,同個支系的瀏覽器很可能已經跟祖先支援的標準沒什麼關係了
但是基於相容性的考量,以前的userAgent的內容也往往會被繼承,並添上新的標準的標示
以Chrome的userAgent為例
"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.31 (KHTML, like Gecko) Chrome/26.0.1410.64 Safari/537.31"

"KHTML"是最早期的瀏覽器標準之一,已經跟現代瀏覽器的標準沒什麼關係了
"Safari"也是Chrome剛推出時,為了標明相容Safari的標準規格而加上去的
其餘的標示依此類推,可以知道userAgent並不是那麼明確
特別是行動版本的瀏覽器因實作廠商眾多,userAgent更是混亂
要判斷行動瀏覽器版本可參考之前的文章

雖然userAgent並不是完全符合瀏覽器的狀況,但要判斷瀏覽器版本也只能靠它了
以下實作簡單的判斷瀏覽器的版本

JavaScript DOMContentLoaded 事件使用

這個事件很接近JQuery的 ready() function,是HTML5規格的新事件
事件的執行時間可參考下圖


一般常見到將要在文件載入時就立刻執行的程式碼寫在onload事件裡
但onload事件的發生時機是在整份HTML文件載入完成,包含圖片等額外資源
如果那些資源很龐大,則會延遲事件的執行時間,並會讓使用者看到未處理過的頁面

DOMContentLoaded事件則是在 DOM載入完成後發生
在過去要做到相同的效果,常見作法是將script寫在HTML文件的最下方
另外也有一些要繞點遠路的做法,或是乾脆使用framework
隨著HTML逐步地擴展規格,倚賴framework的需求也逐漸下降
實際的使用方式如下,並附上相容舊瀏覽器的作法

Java 物件容器筆記

在Java裡,對於物件的收集、處理有兩種不同的概念
1.Collection -
   收集物件並形成一個具有相同處理規範的物件集合
   List 在收集物件時會記錄其索引順序,所以可藉由索引取回物件
   Set 會過濾掉已經收集過的物件,形成一組不重複的物件集合
   Queue 以佇列的形式收集物件,對於佇列兩端的物件有較方便的操作

2.Map -
   Map是一群成對的key-value物件,讓使用者可以透過另外一個物件查詢目標值
   對於物件集合,提供了搜尋的方便性

Responsive Web Design

Responsive Web Design,簡稱RWD
這是這幾年行動裝置興起後,才變的熱門的設計方式
讓網站能依照裝置的解析度而呈現不同的排版、外觀
好處是寫一份HTML就能對應各種瀏覽平台,比起開發Native App的成本來的低
如果要轉換成原生App也有PhoneGap等框架可以選擇

但是不管怎樣的設計方式,如何帶給使用者最好的瀏覽體驗
RWD比起一般設計有更多的考量,例如:
1.在mobile平台上不會有 hover 的行為存在
2.mobile平台上的操作多以點擊(click)的方式進行
  也要思考如何提供一個簡化的操作流程,增進使用者在行動平台的易用性

也因為開發出一份符合各種平台的使用習慣的設計並不簡單
所以不是一昧的在開發上選擇RWD就好了,須依需求選擇開發方式
如果選擇RWD開發,也建議從版面最簡單的行動版本開始,逐步拓展到較複雜的介面

偵測行動瀏覽器

很多網站除了桌面版本外,也會另外提供行動版本的網站
當然現在RWD的設計很流行,只是也不是所有的聲音都贊同就是
不過再說到這些設計需求時,有一個先決條件是要先判別瀏覽器是否為行動版本
判斷上我們會使用User-Agent當依據,這裡不多說
Detect Mobile Browsers 這個開源工具庫提供了方便判斷的小工具
而且具有Apache、ASP.NET、JSP、Python、C#、Rails等各種語言的版本

以下用最新下載的JavaScript版本(2013/3/27下載)來看

Chrome 設定小於12px的 font-size CSS 顯示問題

Chrome瀏覽器的 "進階設定" 預設網頁顯示的字體大小最小為12px
所以會有雖然CSS設定了 font-size 小於12px,但卻無法生效的情況
以前的解決方式是在CSS增加 -webkit-text-size-adjust:none; 這行
不過這個屬性已經不再被Chrome支援了,所以不要再想這件事吧...XD

Chrome 的這個設定算是設計上的思考,而不是bug
很多字體、特別是中文字之類結構較複雜的文字,在小尺寸時易變形、模糊
而維持 12px 也是讓瀏覽器上的閱讀保持易讀性的方法之一

範例 - JavaScript 實作可拖曳排序清單(sortable list)

這篇文章接續拖曳物件的教學
利用之前寫好的架構再接續較複雜的行為
示範的目標是一水平排列的清單內容,並做到藉由拖曳清單項目改變其排列順序
首先準備好兩種CSS,分別給一般狀態以及拖曳中狀態下的清單項目使用
.undrag {
    position:relative;
    z-index: 1;
    opacity: 1;
    filter: alpha(opacity=100);
    top: 0px;
    left: 0px;
    cursor: pointer;
}
.drag {
    z-index: 100;
    position:absolute;
    opacity: .50;
    filter: alpha(opacity=50);
    cursor: move;
}

範例 - JavaScript 實作可拖曳物件

實作成果示範


物件拖曳的重點在於物件位置的計算公式 - 目前滑鼠位置-起始滑鼠位置+目標位置
單純拖曳物件的話不算困難
說的上比較困難的是拖曳之後要結合的動作(如:drop、sortable list等)
雖然HTML5有Drag相關的API,不過這邊就先不提了
先做出一個能相容於老舊瀏覽器(IE)的版本
GitHub檔案目錄

PhoneGap 2.x包裝HTML文件為Android App

PhoneGap是一個行動開發框架
目的是讓開發者使用HTML5技術開發應用程式後,就能快速的部署到各平台
使開發者能專注在程式本身及減少學習上的成本
HTML5應用程式經過PhoneGap轉換後會變成原生應用程式
網頁本身會使用平台核心的瀏覽器功能讀取,例如:android.webkit.WebView
而透過呼叫PhoneGap的API,應用程式就能使用平台原生的相機功能、影片、音樂等

PhoneGap的官網:http://phonegap.com/
教學引導

在被Adobe買下後,PhoneGap的核心被捐贈給Apache基金會,並改名為Apache Cordova專案
本篇文章僅示範PhoneGap在Android平台的簡單使用
以Eclipse IDE為示範進行開發,建議先參考Android SDK開發環境設定
以下為開發工具版本,對於2.x版應該都適用
Eclipse:4.2 Juno
PhoneGap:2.5.0

Android SDK開發環境設定

開發Android程式需先安裝Java的JDK工具和Android SDK
Java的安裝參考以前文章,Android開發者網址為http://developer.android.com/sdk/index.html
在之前,Google的作法是將安裝套件拆開讓開發者自行搭配
但因為使用率不彰的關係,現在整合成ADT(Android Developer Tool)簡化開發者的安裝步驟
裡面包含了SDK本身、AVD模擬器以及Google為Android設計的Eclipse版本
雖然說開發不限定IDE的類型,但Eclipse是Google投入最多資源協助的IDE

HTML Element 使用整理

本篇文章專注於HTML標籤,盡量少提 JavaScript和CSS

一個網頁的格式大致如下:
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title>Index</title>
    ...
</head>

<body>
    ...    //元素標籤撰寫處
</body>
</html>

Doctype標籤宣告html文件版本
在過去會看到各式各樣的宣告,如html4:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">

在過去的發展中,HTML有各式各樣的版本,目前最新的為HTML5
在HTML5以後只要使用<!DOCTYPE html>就能宣告為網頁文件
以後的版本也只要這樣即可,而且這個標籤能相容於舊瀏覽器

<meta>元素包含在<head>元素內,紀錄網頁的相關資訊
這些資訊並非記載給使用者看,而是提供給搜尋引擎
使用上透過name屬性標註網頁特性,content屬性則記錄特性值,能設定的大致如下:

<meta name="description" content="test page" />
description描述網頁特性給搜尋引擎,最多能用155字元

<meta name="keywords" content="test,html" />
keywords包含了使用者可能用來搜尋此網頁的字詞清單,使用","分隔
目前對搜尋引擎的索引效果已經不大了

<meta name="robots" content="nofollow" />
robots標明搜尋引擎是否該加入頁面到搜尋結果中,不想被加入的話指定值為noin…

範例 - JavaScript 替換瀏覽器預設滑鼠右鍵選單

這次實作的功能是要替換瀏覽器在網頁被點擊滑鼠右鍵時跳出的選單
改成跳出自製的選單

滑鼠的一個點擊(click)就會引發3個事件
點擊滑鼠左鍵的話,依序是 onmousedown -> onmouseup -> onclick
如果按下的是滑鼠右鍵,則依序是 onmousedown -> onmouseup -> oncontextmenu

瀏覽器的預設右鍵選單通常在執行 oncontextmenu 前就會先出現(display)
所以我們就必須在 onmousedown or onmouseup 時事先處理 oncontextmenu 事件
在 firefox 18.0.1 時會發現其在 oncontextmenu 時處理的頁面狀態與點擊發生前相同
所以要對應 firefox 的跨瀏覽器處理,還要注意oncontextmenu事件是否使用前面事件的物件
實作程式碼如下:

在table裡使用套用overflow屬性

要在 table 中使 overflow 生效,需多做一些CSS設定
對table設置 table-layout:fixed;
然後在要設定此屬性的 table element(如td)裡再設置以下CSS屬性
white-space:nowrap;     /* 避免折行,雖然在部分瀏覽器中不加這行也可以 */
overflow:hidden;    /* 或者是讓它自動出現scroll,overflow:auto; */