[WebApp]定寬網頁設計下,固定寬度布局開發WebApp並實現多終端下WebApp布局自適應


前言


由於博主最近寶寶出生,工作上更換項目組,白天晚上都比較忙碌,所以最近未登陸博客園,一些童鞋得留言未能及時查看回復,在此表示歉意。由於留言的童鞋大部分是希望我能發送一份測試代碼,為了一勞永逸,我把測試代碼貼到了本文最后,方便大家及時獲取。如有問題請留言,鑒於剛才提到的原因,回復可能不及時,望見諒。謝謝。

 

本文中所指Mobile WebApp是指運行在Mobile WebKit瀏覽器上的WebApp。本篇文章講解如何像傳統PC網頁開發一樣,使用定寬布局開發WebApp,並讓WebApp適應多終端設備:

  1. 不使用Mobile UI框架
  2. 不使用響應式布局
  3. 適配多終端,適配WebApp布局寬度為終端設備分辨率寬度
  4. 一套CSS代碼,一套布局方案
  5. 可以實現復雜的UI界面
  6. 支持iPhone、Android

 

閑扯


目前主流的WebApp UI開發框架有jQuery MobileSencha Touch等,這些框架在處理不同設備分辨率的適配時,采用響應式布局和基於百分比的形式顯示UI組件,UI可以根據設備的不同尺寸進行呈現

雖然jQuery Mobile等框架很強大,但是在開發UI復雜的界面時,還是力不從心:百分比設置寬度不能適應復雜的布局要求。這時就需要固定寬度布局的開發方式了,但是網上的資料都在講述“定寬網頁設計,並不適用於多終端兼容的情況”,jQuery Mobile等框架也沒有提供良好的解決方案,固定寬度布局在移動設備上真的不可行嗎?

如果真的不可行,我也不需要寫這篇文章了,哈哈。。。(不要扔板磚,下面進入正題)。。。

 

一、iPhone、Android自帶瀏覽器如何顯示定寬布局頁面


viewport是網頁可繪制的區域。雖然viewport可視面積和屏幕尺寸相匹配,但viewport有其自己的尺寸,確定網頁的像素數量。也就是說,網頁的像素數量超過定義的viewport尺寸,而不是設備屏幕尺寸的屏幕面積。例如,雖然設備屏幕上可能是480像素寬,viewport800像素寬,這時網頁設計定寬800像素的頁面可以正好完全顯示在屏幕上。

例如下面的代碼片斷,為HTML文檔指定viewport屬性。viewport的寬度為匹配設備屏幕的寬度,且禁用縮放。 

<head>
    <title>WebApp</title>
    <meta name="viewport" content="width=device-width, user-scalable=no" />
</head>

iPhone 和 Android 平台上,WebKit 內核的瀏覽器使用 980 像素寬的視見區或邏輯尺寸,相當於viewportwidth=980px。當頁面加載后,內容通常被完全縮放以便整個頁面都可見,盡管內容會被縮放得非常小,甚至不可讀。下面使用一個簡單的定寬布局頁面,在部分手機里使用自帶瀏覽器訪問,顯示情況如下:

 

 

 

 

可以看到,部分手機中頁面會縮得很小,另外的手機中,頁面被放大,出現橫向滾動條。無論哪種形式,都影響用戶的使用體驗。 

 

二、如何讓定寬布局的WebApp在iPhone、Android自帶瀏覽器中,自適配終端,完美顯示 


iPhone3GS及以上設備的Safari支持修改viewportwidth來改變頁面的縮放情況,你可以將width指定為頁面設計的寬度,如此一來,你的頁面正好充滿viewport並全屏顯示,而不會縮放。如當頁面設計寬度為480px時,可以設置viewportwidth=480px

<meta name="viewport" content="width=480px, user-scalable=no" />

 

遺憾的是Android4.0以下的手機系統自帶瀏覽器中,不支持設置viewportwidth,沒關系,Android自帶瀏覽器支持設置另一參數target-densitydpi來達成目的。經過測試,不同分辨率的手機上,如下值可以讓定寬頁面設計的網頁正好填充全屏寬度,而沒有滾動條:

手機

分辨率寬度

布局寬度480px

布局寬度640px

devicePixelRatio

HTC Wildfire(G8)

240px

240dpi

320dpi

0.75

HTC Hero(G3)

320px

240dpi

320dpi

1

GT-I9100G

480px

240dpi

320dpi

1.5

Nexus S

480px

240dpi

320dpi

1.5

MT-870

540px

213dpi

284dpi

1.5

MX032

640px

240dpi

320dpi

1.5

note2

720px

213dpi

284dpi

2

I9308

720px

213dpi

284dpi

2

GT-N7108

720px

213dpi

284dpi

2

GT-I9228

800px

192dpi

256dpi

2

從這一庹數據中,會不會有一個放之眾Android機而皆准的公式呢?

 

各位願意偷懶的不用自己推了,就死我的腦細胞就可以了,就是下方這一條了:

target-densitydpi = UI-width / device-width * window.devicePixelRatio * 160;

  //UI-width :WebApp布局寬度
  //device-width :屏幕分辨率寬度

其實在上面的一庹數據中,note2GT-I9228target-densitydpi 是在得出公式計算出來,並驗證了的。

 

將Android的處理方式應用到剛才的頁面,在上圖中的手機中訪問以作測試:

 

 

觀察上圖可見,在所測試的手機上,測試頁面均自適配到手機屏幕的分辨率,全屏顯示且無橫向滾動條。

 

三、固定寬度布局WebApp多終端自適配方法總結


1iPhone上,指定viewport width等於頁面設計寬度:

<meta name="viewport" content="target-densitydpi=device-dpi, width=480px, user-scalable=no" />

2、Android上,根據公式計算得出target-densitydpi的值,指定到viewport

get-target-densitydpi = UI-width / device-width * window.devicePixelRatio * 160;

//UI-width :WebApp布局寬度 //device-width :屏幕分辨率寬度
<meta name="viewport" content="target-densitydpi=get-target-densitydpi, width=device-width, user-scalable=no" />

 

后記 


到了這一步就簡單了,寫一個函數針對平台設置不同的viewport屬性,只需接收網頁設計寬度即可完成設置。

不過在部分手機上,screen.width值不不一定等於屏幕分辨率,如三星 I9100G。該如何處理,等總結完成后寫到新一篇里。。。

 

 

補充:自適應腳本和測試Demo 


補充:之前因為代碼未整理和詳細測試,未能貼出來,以至於很多童鞋在評論區留言希望發送代碼,在此表示抱歉。終於下定決心整理了一遍,並經erldy童鞋測試,應無大問題了,現貼出來,方便大家使用。如有問題和意見,請留言。這里對erldy童鞋的建議和測試表示感謝。

代碼如下:

/*
 * 使用說明:
 * 本程序以完成固定寬度布局的網頁在iPhone/Android設備上瀏覽時可以適配設備屏幕寬度(豎屏瀏覽, 暫未支持橫屏瀏覽)
 * 為目的。正常運行的環境是: iPhone/Android設備的自帶瀏覽器.
 * 如有問題,意見或建議,請到我的博客頁面留言,或發送郵件.
 * 其他移動版瀏覽器的適配問題, 不在本程序處理范圍, 若有相關問題, 請留言或發送郵件.
 *
 * 博客頁面地址:
 * http://www.cnblogs.com/plums/archive/2013/01/10/WebApp-fixed-width-layout-of-multi-terminal-adapter-since.html
 * 郵箱: limuchen12@126.com
 * 
 * 在引入本程序后,請執行如下兩步操作:
 * 1、對於js不能夠正確獲取到屏幕寬度的設備, 請使用
 *    adaptUILayout.regulateScreen.add(設備name, 設備userAgent字符串標示或正則, {
 *        width : 設備width,
 *        height : 設備height
 *    });
 *
 *    //Example:
 *    adaptUILayout.regulateScreen.add('三星 I9100G', 'GT-I9100G', {
 *        width : 480,
 *        height : 800
 *    });
 * 錄入設備屏幕尺寸, 以便程序可以正確的處理適配.
 * 也可以將已知設備的尺寸都錄入程序.
 *
 * ### 對於如上數據, 大家也可以到我的博客頁面留言板塊貼出來與大家分享, 
 * 我會收集並添加到程序中去, 以互相幫助, 減少大家的整體工作量. 謝謝!
 * 
 * 2、使用如下代碼啟動適配
 *    adaptUILayout.adapt(布局寬度);
 *
 *    Example:
 *    adaptUILayout.adapt(480);
 *
*/
var adaptUILayout = (function(){
    
    //根據校正appVersion或userAgent校正屏幕分辨率寬度值
    var regulateScreen = (function(){
        var cache = {};
        
        //默認尺寸
        var defSize = {
            width  : window.screen.width,
            height : window.screen.height
        };
        
        var ver = window.navigator.appVersion;
        
        var _ = null;
        
        var check = function(key){
            return key.constructor == String ? ver.indexOf(key) > -1 : ver.test(key);
        };
        
        var add = function(name, key, size){
            if(name && key)
                cache[name] = {
                    key : key,
                    size : size
                };
        };
        
        var del = function(name){
            if(cache[name])
                delete cache[name];
        };
        
        var cal = function(){
            if(_ != null)
                return _;
                
            for(var name in cache){
                if(check(cache[name].key)){
                    _ = cache[name].size;
                    break;
                }
            }
            
            if(_ == null)
                _ = defSize;
            
            return _;
        };
        
        return {
            add : add,
            del : del,
            cal : cal
        };
    })();
    

    //實現縮放
    var adapt = function(uiWidth){
        var 
        deviceWidth,
        devicePixelRatio,
        targetDensitydpi,
        //meta,
        initialContent,
        head,
        viewport,
        ua;

        ua = navigator.userAgent.toLowerCase();
        //whether it is the iPhone or iPad
        isiOS = ua.indexOf('ipad') > -1 || ua.indexOf('iphone') > -1;
    
        //獲取設備信息,並矯正參數值
        devicePixelRatio = window.devicePixelRatio;
        deviceWidth      = regulateScreen.cal().width; 
        
        //獲取最終dpi
        targetDensitydpi = uiWidth / deviceWidth * devicePixelRatio * 160;

        //use viewport width attribute on the iPhone or iPad device
        //use viewport target-densitydpi attribute on the Android device
        initialContent   = isiOS 
            ? 'target-densitydpi=device-dpi, width=' + uiWidth + 'px, user-scalable=no'
            : 'target-densitydpi=' + targetDensitydpi + ', width=device-width, user-scalable=no';

        //add a new meta node of viewport in head node
        head = document.getElementsByTagName('head');
        viewport = document.createElement('meta');
        viewport.name = 'viewport';
        viewport.content = initialContent;
        head.length > 0 && head[head.length - 1].appendChild(viewport);                
    };
    
    return {
        regulateScreen : regulateScreen,
        adapt : adapt
    };
})();

 

 

 

測試代碼:

<!doctype html>

<html>
    <head>
    <meta charset="utf-8" />
        <meta name="viewport" />

        <style>
        html, body, h2, div {
            margin : 0;
            padding : 0;
        }
        
        body {
            background : #F7F7F7;
        }
        
        .download {
            float : left;
            width : 480px;
        }
        
        .download h2 {
            margin : 10px;
            font-size: 30px;
            background: rgba(0, 0, 0, .1);
            line-height: 50px;
            text-indent: 0.2em;
        }

        .projectList li {
            font-size : 30px;
            line-height : 50px;
        }
        </style>
    </head>
    
    <body>
        <div class="download">
            <h2 event="call-test-fn">my WebApp : width 480px</h2>
            <ul class="projectList">
                <li><a href="#">粑粑拉</a></li>
                <li><a href="#">哈利波特大</a></li>
                <li><a href="#">負周幾</a></li>
                <li><a href="#">尼美</a></li>
            </ul>
        </div>
        
 
        
        <script>
        adaptUILayout.adapt(480); //適配當前頁面
        </script>  
    
    </body>

    
</html>

 

 

 

 

 

------------------------------------------------------------------------------------------------------

  本篇文章為博主原創,如需轉載本篇文章,請保留原始地址:、

  http://www.cnblogs.com/plums/archive/2013/01/10/WebApp-fixed-width-layout-of-multi-terminal-adapter-since.html 

------------------------------------------------------------------------------------------------------

 

本文發布以來,有很多童鞋瀏覽,提問交流,卻腫么只有2個推薦捏,反對竟然也一個都沒有?交流啊,要交流啊騷年們。

如果本文有幸吸引您閱讀到這里的話,那俺就厚着臉皮問您要一個推薦,如果您覺得本文無什可取之處,那您就反對一下,若果能得到您對本文的留言,那就是俺莫大的榮幸。

最后,感謝您閱讀本文,工作愉快。。。 

 

 


免責聲明!

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



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