怎麼判斷裝置的瀏覽器尺寸

不同的屬性

  • clientHeight
    • 完整可以顯示的高度
  • offsetHeight
    • 包含瀏覽器的 padding 就是那些邊框
  • scrollHeight
    • 包含邊框還有滾軸展開的高度

在行動裝置下取得尺寸

<html>
<head>
<title>取得尺寸</title>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no,minimum-scale=1.0,maximum-scale=1.0" />
<script type="text/javascript" src="http://code.jquery.com/jquery-1.7.1.min.js"></script>
<script>
$(document).ready(function () {
$("#spanClientHeight").text(document.documentElement.clientHeight);
$("#spanClientWidth").text(document.documentElement.clientWidth);
});
</script>
</head>
<body>
<div>
高度:<span id="spanClientHeight"></span>
<br />
寬度:<span id="spanClientWidth"></span>
</div>
</body>
</html>

這邊取得到的會是行動裝置解析度的寬度,而不是真實寬度。

image

利用 ViewPort 取得真實寬度

<meta name="viewport" 
content="width=device-width, initial-scale=1.0,
user-scalable=no,minimum-scale=1.0,maximum-scale=1.0" />

設定 viewport 之後瀏覽器就不是根據解析度去顯示而是實際螢幕大小

image

Demo 頁面

連結

image


clientHeight/clientWidth returning different values on different browsers

CSS / JavaScript – How do you get the rendered height of an element?

element.clientHeight – MDN

Android 2.x 使用 jQuery Mobile 設定 Position:fixed , Select 會無法正常顯示

在 jQuery Mobile 中可以設定 Header 跟 Footer 為 Fixed(這邊有官方文件),不過為了要能夠支援多種裝置效果,這邊的 Fixed 是用 javascript 去控制高度,而不是用 CSS 的 Position:fixed 。下面是有支援 Position:fixed 的裝置對應表。
image
(資料來源)
在 Android 2.x 的版本下,Position:fixed 必須配合 ViewPort  的設定 user-scalable = 0 的情況下才能作用。但是當 Andriod 2.x 的 Position:fixed 作用時,jQuery Mobile 的下拉選單會沒有辦法在 Android 裝置上展開。

重現這個問題

首先到 jQuery Mobile 官網複製官方建議的基本架構

<!DOCTYPE html> 
<html>
<head>
<title>My Page</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="http://code.jquery.com/mobile/1.1.0-rc.1/jquery.mobile-1.1.0-rc.1.min.css" />
<script src="http://code.jquery.com/jquery-1.7.1.min.js"></script>
<script src="http://code.jquery.com/mobile/1.1.0-rc.1/jquery.mobile-1.1.0-rc.1.min.js"></script>
</head>
<body>

<div data-role="page">

<div data-role="header">
<h1>My Title</h1>
</div><!-- /header -->

<div data-role="content">
<p>Hello world</p>
</div><!-- /content -->

</div><!-- /page -->

</body>
</html>

加入測試的 Select 下拉選單

<div data-role="content">
<p>Hello world</p>
<select>
<option>Google</option>
<option>Yahoo</option>
<option>Bing</option>
</select>
</div>

加入 Position: Fixed

<div data-role="header" style="position: fixed; width: 100%;">
<h1>My Title</h1>
</div>

加入為了在 Andriod 2.x 能夠啟用 Position: Fixed 效果必須的 user-scalable=0

<meta name="viewport" content="width=device-width, user-scalable=0, initial-scale=1">

使用模擬器顯示畫面

image

接下來點下下拉選單。

image

沒有看錯,除了在邊邊出現藍色邊框證明有點過之外其他什麼事情都沒有發生。

正常情況下應該是會出現下方這張圖片的樣子。

image

要回復正常彈出下拉選單,只要將 position: fixed; 或是 user-scalable=0 移除就可以了。這是因為只要將 user-scalable=0 移除,position: fixed; 就沒有作用了(測試版本是 Android 2.3.1 Flayer)。 順便一提,這兩個版本在 IOS4 ,IOS5 ,Windows Phone7 下都是沒有問題的,IOS4, Windows Phone7 完全不支援 position: fixed;,而 IOS5 則是完全支援。

Demo

下拉選單不正常彈出

image

下拉選單正常彈出

image


Native select Menu no event on Adroid 2.2 or above

利用 ThemeRoller 設計版面

themroller-mobile-logo
我是到前一陣子才發現 ThemeRoller 這個好用到一個不行的工具,調整版面對我來說實在是一個很痛苦的事情,又是哪個東西改個顏色、改個寬度、改個配色,東修西改一半的開發時間都花在這上面了。如果有要用 jQuery Mobile 來開發的人,強烈建議一開始就使用 ThemeRoller
image
一開始進入頁面就可以看到這個編輯器,預設會先有三個空白的 theme 可以做設定,而左側功能列就是有相關的選項可以做選擇,可以看到基本模組都是可以做調整的。在設定完之後只要按下左上方的 Download Theme 就可以做匯出的動作,include 的方法也非常簡單,匯出的時候就有說明了。
image
在右上方輸入 Theme 的自訂名稱,並且在下載之後加入專案當中,也要在頁面中引用,要在 jQuery Mobile 的 js 跟 css 之前。不過有用過  jQuery Mobile 原本就有預設五種 Theme 可以使用,在官網也有介紹,當一加入 ThemeRoller 產生出來的 css 檔案之後,原本的 Theme 效果就會被覆蓋掉了,如果說想要保留原本的預設樣式要怎麼做呢?幸好還有另外一個 import 功能。
image
選擇右上角的 Import Default Theme 就可以載入 jQuery Mobile 預設的範本,不用害怕會覆蓋掉現在已經在運作的 jQuery Mobile ,或是說如果想要預設的樣式還要自己設定,如果已經有 ThemeRoller 匯出的檔案也只要複製 css 直接匯入就可以看到之前修改的結果。
image
image
如果開啟 Inspector 可以直接點選畫面上想要調整的地方,左側功能列表就自動開啟相對應的設定
官方還有另一個 valencia 樣式可以選擇。
image

利用 Swipe Event 控制換頁

image
Carousel 效果是我認為在 Mobile 上面最難處理的部分,大部分的作法都是用一個長條 div 只顯示其中一部份,再用 css : Left 或是 Top 去控制顯示的部分。如果是 jQuery 早期的動畫效果 jquery.animate() 就算是 ipad2 跑起來也是超頓的,唯一的解法就是利用 –webkit-Transform 來做處理。
在 jQuery Mobile 上面預設在換頁的時候就會觸發 –webkit-Transform 來處理換頁的特效(在不支援的瀏覽器上面會直接換頁顯示),但是這邊的特效跟其他 Framework 呈現方式比較不一樣的是在觸控移動的時候 jQuery Mobile Swipe 的方式是當使用者手指移動超過一段距離之後,就觸發 Swipe 事件。其他的 framework 如果有將 touchstart ,touchmove ,touchend 分別做處理的話,就可以在手指移動的同時就做畫面移動的效果,然後在 touch end 手指離開計算距離決定要不要呈現下一頁,抑或是距離不足就停留在原本頁面。jQuery Mobile 目前看起來沒有太重視這一塊,感覺他們的主要目標還是在容易開發、廣泛支援上面。

Swipe Events

基本上 jQuery Mobile 就是讓你很容易套用,所以要取得滑動的事件只要註冊 swipe event 就可以了,jQuery Mobile 利用 javascript 的 touch event 如果長度超過一定距離就觸發 swipe event。

  • 預設在一秒之內移動水平距離超過 30px 而且垂直小於 20px ,就會觸發 swipe 事件。
  • $.event.special.swipe.horizontalDistanceThreshold = 130; 設定 horizontalDistanceThreshold 參數,將原本水平移動距離 30px 改為 130px 之後,他才會觸發 swipe 事件,這邊就是根據測試的習慣來修改,避免因為太容易換造成其實 user 並沒有想要換頁,但是事件被觸發。
  • durationThreshold Swipe 動作要在多少時間下被完成,如果超過這個時間就不觸發 Swipe 事件,預設 1000 (ms)。
  • verticalDistanceThreshold 垂直移動不能超過多少(px)才觸發 Swipe。
  • scrollSupressionThreshold 水平移動超過多少(px)就停止原本垂直滾動。

Example

一開始我先建立一個 js 物件

Site: {
PrePage: { Url: "" },
NextPage: { Url: "" }
}

全網站註冊 Swipe 事件,只註冊一次

$(document).ready(function () {
$.event.special.swipe.horizontalDistanceThreshold = 130;
$(document).bind("swipeleft", function (e) {
$.mobile.changePage(Site.NextPage.Url, { transition: 'slide' });
});
$(document).bind("swiperight", function (e) {
$.mobile.changePage(Site.PrePage.Url, { transition: 'slide', reverse: true });
});
});

在每一頁載入的時候去修改物件的值

$('div:jqmData(role="page")').live('pageinit', function () {
Pru.Site.PrePage.Url = '@(PreviousSibling.Url)';
Pru.Site.NextPage.Url = '@(NextSibling.Url)';
});

這邊我是用 mvc3 Razor 搭配 ASP.NET MVC SiteMap provider 來控制,強力推薦 ASP.NET MVC SiteMap provider 很好用喔。全網站事件我只有註冊一次,如果在每一次 pageinit (pageint 是 jQuery Mobile 事件,ajaxload 新頁面進來觸發) 重複註冊的話,就會變成一次 swipe 換了好多頁。也有考慮過利用 bind unbind 來控制,但是似乎不是很容易,目前感覺上還是用 js 物件操作會比較方便。


jQuery Mobile | jQuery Mobile

jQuery Mobile #2 切換頁面的特效處理

jQuery 只是 plugin 但是 jQuery Mobile 是 Framework ,他在一引用的時候就自動幫你擋掉所有 A.Link 的動作,就是要你照他的規矩來玩。也有內建很多效果在 A.Link 切換頁面的時候來展現。雖然說效果不比 Sencha Touch 或是其他的 Mobile js Framework ,但是 jQuery Mobile 強調的就是多支援,支援度絕對沒有別家比得上,不用再花很多時間去調整各家瀏覽器、各家 OS 還有各家 OS 上的不同瀏覽器,講到舌頭都打結就知道支援度是多麼可怕的東西。

data-transition

<a href="index.html" data-transition="pop">彈出效果</a>

jQuery Mobile 利用 data-transition 來設定不同的效果,有 slide , slideup ,slidedown ,pop ,fade ,flip 都只要設定上去就可以看到效果了。

<a href="/index.html" data-transition="reverse slide" class="上一頁">

Slide 預設是由右方滑入,如果想做左邊一頁的話就是要設定為 reverse slide 。非常貼心的一點是,當套用效果切換頁面的時候,這時候回上一頁也會使用反向的效果來顯示。

data-rel=”dialog”

<a href="/index.html" data-rel="dialog">

設定 dialog 的情況下,連結頁面會用彈出的來顯示,而且彈出不會記錄在瀏覽器的 history 裡面,上下頁就不會切到彈出這頁。

rel=”external”

<a href="/index.html" rel="external">

如果連結的位置是由 http://||https:// 開頭,jQuery Mobile 就不會幫你做任何處理,直接開啟新頁面。但是如果在內部連結可是也不想要 jQuery Mobile 做什麼事的話,就加上 rel=”external” ,假設說新頁面沒有依照 jQuery Mobile 的 Html 規範走的就必須加上,不然再 ajax loading 的時候就會因為判讀不正常出現 error。


http://jquerymobile.com/test/docs/pages/page-transitions.html

jQuery Mobile #1 開始建立一個新的 jQuery Mobile 專案

image

這幾天非常的慘烈,奉勸如果有想要進來開發 Mobile Web 的同好,一定要謹慎評估 Framework 的使用,話說最初我也是非常堅持在效果上,如果能做到像 app.ft.com 這種水準的網站,真的是作夢都會笑。不過最終繞了一大圈,我還是又回到了 jQuery 的懷抱。當然有非常多的原因,時程的壓力、擴充性跟可維護性、不過讓我最後下定決心的還是因為客戶希望時程內要能在 windows phone & IE 上正常瀏覽。

雖然百般無奈,但是開始用了 jQuery Mobile 三個小時之後,其實比我想像中的還要好一些。而且最重要的是,我開始懷抱過年可以賴在家看電視的夢想了。

基本 html 架構

<!DOCTYPE>
<
html>
<
head>
<
title></title>
</
head>
<
body>
<
div data-role="page">
<
div data-role="header">
</
div>
<
div data-role="content">
</
div>
<
div data-role="footer">
</
div>
</
div>
</
body>
</
html>

  • 如果要使用 jQuery Mobile 預設會需要這幾個 div 用 data-role 去設定,分別是 page,header,content,footer,有了這幾個 div 預設的動作才會正常,不然會一直呈現鬼打牆狀態,像是超連結點下去沒有反應之類的…。我第一件發現的事情是 jQuery Mobile 把全部 <a> 的動作都吃掉了(如果超連結是 http:// | https:// 開頭的不會,吃掉的是站內連結),預設會取代成 ajax loading 來做換頁的效果。
  • 使用預設的 ajax loading 的時候,載入的頁面也必須包含這幾個 div , jQuery Mobile 在背景做 loading 頁面的動作,然後把 <div data-role=”page”></div> 之間的資料做更新的動作。
  • jQuery Mobile 最大的優點就是他真的在跨瀏覽器上面做了很多的功夫,像是 pushState 還有 webkit transform 這些很不錯但是又有人不支援的功能,都有默默的判斷。如果說將來 Mobile OS 市場愈來愈多人加入戰局的話,考慮使用 jQuery Mobile 的應該也會大增。


jQuery Mobile | jQuery Mobile

Mobile Web #5 判斷網路連線狀態

image

為了判斷網路連線的狀態,各家瀏覽器都有支援判斷的 js 語法,不過 IE 並不跟著走。

Internet explorer

這邊有很詳細的介紹

http://help.dottoro.com/ljcuiwad.php

Other Browsers

利用 navigator.onLine 可以抓到網路卡的狀態,不過並不一定是實際網路,如果是中間的 router 掛掉,或是伺服器真的有問題就沒這麼容易判斷囉。

    <script>
var
statusElem = document.getElementById('status')

setInterval(function () {
statusElem.innerHTML = navigator.onLine ? 'online' : 'offline';
}, 250);
</script>


http://html5demos.com/nav-online

http://help.dottoro.com/ljcuiwad.php

Mobile Web #4 利用 application caching 減少網路延遲

一直以來 Web 都有一個問題,就是網路連線的問題,連線的品質確實影響了 Web User Experience,以往在這情況下,我都會說”去怪你的網路公司吧”。但是到了 Mobile 裝置上,這個情況更顯得嚴重了,並不是罵一罵 3G 廠商就能解決的,就算稍微好心增加一點頻寬,也並不能消除連線問題。只能想辦法讓 User Experience 盡可能提升。

browser caching & application caching

既然如此要提升User Experience 的話當然就是在本機資源上作手腳,瀏覽器本身也就包含了 caching 的功能,不過以往的 browser caching 是不容易控制的,在 HTML5 之後把 cache 動作演變成可以從 application 去控制,也可以透過 javascript 去得知以及控制狀態。

manifest

manifest 是 HTML5 的新屬性,負責定義有關於整個網站 cache 的動作,利用 manifest 的設定相關網路 cache 還有連線離線的處理。目前五大瀏覽器除了 IE 之外,其他的最新版本都支援 manifest 。

CACHE MANIFEST
# VERSION 1.0

CACHE:
/favicon.ico
/Content/Images/desktop-icon.png
/Content/Images/startup-icon.png

在 CACHE 之後定義需要 CACHE 的檔案,在 manifest 中定義的 cache files 除非 manifest 檔案有更改,不然都會被視為是同樣的檔案,所以如果在這邊的資源有更改過,那你也必須修改 manifest 檔案(可以在#後面加上版本編號),不然瀏覽器還是會認為是同一份檔案。

NETWORK:  /Home/Member
/Report/

在 NETWORK 的區塊定義需要網路連線的部分,特定檔案或是包含子路徑,在這邊定義的部分不會被 cache 。

FALLBACK:
/Home/Offline

FALLBACK 這邊則是如果網頁在離線的狀態下被開啟(而且並沒有存在 cache 中),則會顯示這個頁面。


http://www.html5rocks.com/en/tutorials/appcache/beginner/

http://www.pluralsight-training.net/microsoft/

Mobile Web #3 如何設定桌面捷徑&啟動 Loading 圖示

IMG_0127

繼上一篇Mobile Web #2 如何在 Mobile 上面呈現 App 般的效果手機在瀏覽網頁的時候,都可以將喜歡的網頁加入桌面捷徑,就是會有一個很像你的 APP 的路徑在桌面上,當你執行的時候就會啟動瀏覽器去開啟這個網頁。

<link rel="apple-touch-icon" href="Content/Images/desktop-icon.png" />

在利用桌面連結啟動之後,連結到頁面。在 iOS 上有區分為使用 Safari 開啟,或是重新啟動一個新的執行續,一樣是使用 Safari 核心,可是包括多執行的下方小清單,都會改成 icon 的圖示。在一開始的版本限制大小為 57×57 , iPad 為 72×72 在 iOS4 之後的高畫質螢幕都支援到 114×114,如果放的是高畫質但是較舊的裝置上瀏覽也會自動降低解析度。

如果要想要在桌面連結執行的時候是一個獨立執行的網頁,而並非用 Safari 開啟的話

<meta name="apple-mobile-web-app-capable" content="yes" />

在獨立執行的時候開啟會比直接加載在 Safari 多一段載入的時間,這時候也可以設定載入時候的 loading 畫面圖片,除了沒有在 AppStore 上架之外,這真的就很像一個 Natïve App 了(還缺少了 push message 的功能)

<link rel="apple-touch-startup-image" href="Content/Images/startup-icon.png">


Reference

這篇有很完整的介紹

http://answers.oreilly.com/topic/2123-how-to-create-a-website-icon-for-the-iphone-and-other-mobile-devices/

How to Create a Website Icon for the iPhone and other Mobile

Mobile Web #2 如何在 Mobile 上面呈現 App 般的效果

最近整個栽在行動版網頁的開發中,看起來小小的螢幕,困難程度卻比一般網頁麻煩多了

1. Mobile 裝置上面的可顯示區域小的多,要如何顯示出真正重要的東西,用一般網頁去設計的話,光是 banner 就佔掉了一大塊空間,還有一大堆東西要放,又是選單又是標題的,還不能太小不然手指頭點不到。

2. Mobile 裝置現在做的真的都很不錯,好到讓人忘記他的硬體完全不能跟一般電腦相比,電腦上跑的好好的 jquery animate 動畫效果 ,在 Mobile 上面看是讓人想哭的慢。

3. 不穩定的連線,有誰用 Mobile 上網的環境都是確定很順暢的,如果在不穩定的環境下上網,丟回來一直發生 404 的畫面,相信大家一定直接關掉了吧。

4.各種機型解析度瀏覽器版本,這原本電腦版網頁也會發生的問題,只是 1960 的螢幕可以接受只有 1280 的畫面,但是 ipad 使用者應該不能接受 iphone 的畫面吧。

綜合以上各點,已經開始逼近解答了,就是 css3 。利用 transform 取代  jquery animate 甚至用 translate3d 做 3d 效果,或是加上 media queries 動態改變排版,只是以台灣目前產業生態來說,css3 這塊到底是網頁設計師還是工程師,css 3 畢竟也只是單純的效果,還是要有 js 的觸發動作,還有很多細節的效果狀態要控制,或許之後 Mobile 不會再有網頁設計師,而是改成前端設計師,將  js 獨立出來一層架構(現在的 ExtJS 就是在做這件事)還要加上設計師的美感跟排版功力。

還有一個問題是並不是每個瀏覽器都可以完整支援 css3 ,不過好險的是目前的 android 跟 iOS 都是預設 webkit 核心瀏覽器,近來很有野心的 Windows Phone7 呢 .. .. 反正聽說 ie10 快出了對吧。

image

(iOS Only) 個人很愛的 app.ft.com ,Financial Times 推出的 Mobile Web ,簡單的畫面,豐富的內容,又很容易上手,連我這個看不太懂英文的都馬上就會用了。利用了 media queries 的功能,在 iphone ipad 或是電腦螢幕上(需要利用 User Agent 模擬)都會看到不同的頁面呈現方式。

image

(Webkit Only) Windows Phone7 推出的 Demo 網頁版,為了讓其他裝置使用者可以體會一下 Metro UI 的魅力,特效炫到一個爆炸,這也是我第一次發現 ie 不能瀏覽的 microsoft 網頁。


Reference