1. 程式人生 > >移動端web開發進階

移動端web開發進階

page 提升 最終 好玩的 ini 進階 body user hang

posted @ 2014-11-24 20:09 vajoy 閱讀(4708) 評論(12) 編輯 收藏

三個月前曾寫過一篇跨終端響應式頁面設計入門的博客,上了博客園頭條也得到了不少關註,今天想在這篇博客的基礎上,繼續寫一篇進階的文章。

技術分享

補充

基於“入門”一文,我想再補充幾個基礎知識點,主要都是針對iOS的meta標簽:

⑴ 允許全屏瀏覽頁面的標簽:

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

⑵ safari頂端狀態欄樣式定義/隱藏:

<meta name="apple-mobile-web-app-status-bar-style" content="blank" />  <!--隱藏狀態欄-->
<meta name="apple-mobile-web-app-status-bar-style" content="black" />  <!--定義狀態欄樣式為暗黑色-->

⑶ ios會把類似電話號碼的數字變為可點擊並添加到電話的連接,我們可以這樣禁用它:

<meta name="format-detection" content="telephone=no" />

另外還有一個個性化的link標簽,它支持用戶將網頁創建快捷方式到桌面時,其圖標變為我們自己定義的圖標。比如手機騰訊網上的標簽:

<link rel="apple-touch-icon-precomposed" href="http://3gimg.qq.com/wap30/info/info5/img/logo_icon.png">

不過騰訊對這個png圖標的命名並不規範,常規我們要求文件名應為 apple-touch-icon.png

apple-touch-icon-precomposed.png ,前者的命名iOS會為這個圖標自動添加圓角、陰影和高亮覆蓋層,後者則不會添加這些效果。

技術分享

提升

移動端web的開發最頭疼的是viewport與常規PC頁面的不同,如果你的頁面是專門針對移動端開發的(特別是使用了meta標簽禁止用戶縮放),這個頭疼的程度會舒緩很多。

個人覺得,對viewport的深入理解,也算打通入門移動web開發的任督二脈之一吧。

我們依舊拿“移動端訪問博客園”的圖例來分析:

技術分享

很多新入門移動端開發的朋友都會誤以為上圖的綠線是窗口的寬度($(window).width())、紅線部分是窗口的高度($(window).height()),但其實不然,任何時候都不應該把PC瀏覽器的窗口概念跟移動端的viewport混淆在一起。

那麽移動端難道沒有窗口寬高?非也,只是正確的“窗口寬高”(稱為viewport的寬高會更靠譜些)應該是這樣的(依舊用綠線和紅線表示):

技術分享

要註意這兩個值,無論你怎麽雙指縮放頁面,它們的大小都是不會變動的(除非頁面內容發生了變化,比如動態生成了一張很大的的img撐大了頁面)。

技術分享

那麽究竟一開始我們“誤以為”了的那個偽窗口的寬高,分別是什麽呢?

它們分別是 window.innerWidth 和 window.innerHeight —— 頁面實際可視區域所展現的像素寬值/高值:

技術分享

或許你會覺得有點好笑,認為直接稱二者為“頁面實際可視區域寬高”不就行了。

其實“所展現的像素”還是不應當舍棄的,因為二者的值是變化的,跟隨著用戶縮放頁面而變化,我們拿window.innerWidth來示例:

技術分享

技術分享

除了上述的,還有一個可能有用的值,它可以獲取設備屏幕寬高,它包含了頂端系統狀態欄、瀏覽器導航條的寬高值,它們是 screen.width 和 screen.height :

技術分享

技術分享

相信你也會想到,如果我們的頁面是專門針對移動端設計的頁面(頁面初始化鋪滿屏幕寬度,且禁用了縮放功能的移動端響應式頁面,例如手機騰訊網),那麽 $(window).width() 、window.innerWidth、screen.width 的值將是相等的(手機QQ內置瀏覽器等奇葩瀏覽器除外)。

既然說到“頁面初始化鋪滿屏幕寬度,且禁用了縮放功能”這個事,我們再順便打個岔聊一下。其功能的實現其實就是添加“入門”一文介紹過了的meta標簽:

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

在“入門”中我也已經介紹過,除了這個標簽,我們還應當在其下增加一行:

<meta name="MobileOptimized" content="320">

最近公司的一個移動端舊項目遇到一個挺好玩的事情跟這個有關,該項目頁面沒有添加MobileOptimized標簽,然後又使用了基於jQuery的swipe.js,然後在其它手機上都能正常顯示幻燈片:

技術分享

但到了iphone 4S- 下就發生了圖片錯位的事情:

技術分享

這是因為swipeJS並不會對瀏覽器窗口大小變化進行重新布局調整(你可以用PC訪問這裏然後縮放窗口試試),而舊版的iphone會默認把頁面做980寬度渲染,但最終以320像素寬度顯示,所以才導致了幻燈片圖片錯位的問題。

可以得知添加 MobileOptimized 標簽,告知ios要以320像素的寬度渲染頁面也是很重要的事情。

技術分享

我們再說說手勢,有時候移動端項目難免會需要一些手勢的支持,而我們也有一些很出眾的手勢庫(比如已經進化到2.0版本的harmmerJS)可供選擇。不過如果項目對手勢的要求不復雜,倒是沒必要引入額外的手勢庫,自己實現一個即可。

常規各種手勢庫都不外乎是基於一下三個事件來實現的:

ontouchstart
ontouchmove
ontouchend

顧名思義,就是觸碰開始、移動、結束時的事件。要註意jQuery對touch系列的支持略麻煩,如事件句柄應再加上一句“originalEvent”(如“e.targetTouches[0].clientX”要寫為“e.originalEvent.targetTouches[0].clientX”),建議直接使用addEventListener來實現:

技術分享
            function dragObj(obj){
                var  $obj = obj,
                     obj = obj.get(0),
                     startX,
                     startY,
                     _x,_y;
                obj.addEventListener(‘touchstart‘, function (e) {
                    startX = e.targetTouches[0].pageX;
                    startY = e.targetTouches[0].pageY;
                });
                obj.addEventListener(‘touchmove‘, function (e) {
                    
                    _x = e.targetTouches[0].pageX - startX;
                    _y = e.targetTouches[0].pageY - startY;
                    $obj.css({"left":$obj.offset().left+_x,"top":$obj.offset().top+_y});
                    startX = e.targetTouches[0].pageX;
                    startY = e.targetTouches[0].pageY;
                    e.preventDefault();
                });
            }
            
            dragObj($("div"));
技術分享

如上方輕松實現了一個拖拽的手勢庫,其中e.targetTouches[0]表示首個觸碰點,我們可以通過e.targetTouches[0].pageX、e.targetTouches[0].pageY 來獲得該觸點的頁面坐標(相對viewport而不是屏幕可視區域),其它的相信都能看得懂也無需逐個介紹了。

要著重提醒的是,在很多移動端瀏覽器(UC啊QQ啊等)上,如果不添加 e.preventDefault() ,會導致touchmove事件僅觸發一次(原生chrome倒是沒有此問題),所以一定要在touchmove事件中加上這句代碼。

至於另一個可能常用到的縮放手勢,我們可以通過判斷touchstart和touchend前後的window.innerWidth是否一致,如果不一致則說明頁面被縮放了。

技術分享

其它常用api

一. 搖一搖

像淘寶的“搖一搖手機獲得紅包”活動,我們可以通過devicemotion方法輕松實現,雖然event.accelerationIncludingGravity這名字長的有點誇張(但也比webGL一堆難記的api好多了):

技術分享
var mobile_motion = {
                        speed: 25,
                        x: 0, y: 0, z: 0, lastX: 0, lastY: 0, lastZ: 0
                    }

$(window).on("devicemotion", function () {
                        var acceleration = event.accelerationIncludingGravity,
                            speed = mobile_motion.speed;
                        mobile_motion.x = acceleration.x;
                        mobile_motion.y = acceleration.y;
                        if (parseInt(flag.isWave_cur) && !flag.isShow_act && (Math.abs(mobile_motion.x - mobile_motion.lastX) > speed || Math.abs(mobile_motion.y - mobile_motion.lastY) > speed)) {
                            //這裏填寫回調事件
                        }
                        mobile_motion.lastX = mobile_motion.x;
                        mobile_motion.lastY = mobile_motion.y;
                    })
技術分享

通過修改speed值可以實現調速,就是要搖多快才能觸發回調。

二. 翻轉屏幕

屏幕翻轉的事件更簡單,通過orientationchange方法來監聽即可:

$win.on("orientationchange", function () {
    //回調事件
})

屏幕在初始化或者翻轉後,都會有一個代表橫屏還是豎屏的值—— window.orientation,通過判斷其值,我們可以得知屏幕當前狀態,甚至知道它是進行了怎樣的翻轉(比如從豎屏順時針轉90度到橫屏),關於它們的值可以點這裏看看,本文就不具體介紹了。

移動端web開發進階