移動端web開發進階


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

補充

基於“入門”一文,我想再補充幾個基礎知識點,主要都是針對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.pngapple-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度到橫屏),關於它們的值可以點這里看看,本文就不具體介紹了。

暫時先寫到這邊吧,由於近期工作忙碌都沒時間碼新文章表示抱歉,由於之前在圖書館看了一本AJAX安全的書籍,后續還想碼一篇關於web頁面安全的總結一下,還有avalon系列的文章,希望我能有時間吧。

好了俺先下班回家去,共勉~

donate


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM