為你的移動頁面尋找一絲新意——手機互動網頁項目總結(下)
為你的移動頁面尋找一絲新意——手機互動網頁項目總結(下)-移動閱讀二維碼

目錄:

一、項目地址

二、布局
1、按屏滾動會碰到什么問題?
2、flexbox會碰到什么問題?
3、fixed定位需要慎用。

三、動畫
1、CSS動畫與Canvas動畫性能優劣分析
2、當縮放動畫碰上硬件加速
3、動畫由Javascript來維護還是css維護的思考

四、特性
1、如何解決音頻播放預加載與延時的問題
2、重力感應
3、啟動原生應用
4、地理定位

五、其它
1、字體圖標應用設計環節的打通
2、當transform碰上模糊

六、數據
1、用戶環境

一、項目地址

1、TGA移動游戲官網

TGA城市拉力賽

 

2、UP+邀請函

3、天天酷跑里約進擊版

二、布局

1、按屏滾動會碰到什么問題?

問題:

按屏滾動即用戶滑動屏幕翻頁,屏幕自動鎖定到當前頁。我們會碰到的問題:

1)、頁面100%高度包含地址欄高度,當地址欄存在時,會有部分內容被隱藏,如下圖所示:

2)、如何阻止瀏覽器默認滾動事件更好?

解決:

1)、重置<html>高度;

document.documentElement.style.height = window.innerHeight + \'px\';

2)、默認事件禁止touchmove比touchstart更好,否則還需要單獨處理<a><input>等問題。

document.documentElement.addEventListener(\'touchmove\', function(e){ e.preventDefault(); }); 

2、flexbox會碰到什么問題?

問題:

自適應高度/寬度的flex元素內,子元素尺寸以百分比為單位(如height:100%)無效。

解決:

需要將子元素設為絕對定位。

3、fixed定位需要慎用。

問題:

在ios系統的瀏覽器中,頁面加載時偶爾會出現抖動情況。

解決:

使用絕對定位或flexbox模擬解決。

三、動畫

1、CSS動畫與Canvas動畫性能優劣分析

問題:

目前移動端動畫,特別在H5游戲與強交互性網站應用非常普遍,常用的實現方式是CSS(硬件加速)與Canvas,但缺乏完整的性能分析數據,我們在選擇動畫實現方式時還是存在糾結。

解決:

選用高中低不同配置不同系統的4款設備,進行了一輪測試:

1)、測試DEMO:

Canvas: 2個元素
Canvas:10個元素
DOM:2個元素
DOM:10個元素

2)、測試數據:

紅色代表警告數據,一般60以上較為順暢。

特征??測試機型 iPhone 4s
(iOS6)
iTouch 4
(iOS5)
三星i9250
(Android 4.0)
三星gt s6358
(Android 2.2)
預計市場份額 中高端(>50%) 中端(35%) 低端(<15%)
Canvas: 2個元素 110 105 95(丟幀) 20
Canvas:10個元素 110 65 65(丟幀) 10
DOM:2個元素 115 80 100 12
DOM:10個元素 60 30 50 5

3)、測試結論:

a、CSS動畫更為流暢、但內存占用過高,動畫元素在5個以內更為推薦;

b、Canvas動畫存在丟幀現象,這一現象在android中低端手機中表現更為明顯;

c、5個以內動畫元素,選用CSS動畫,80%的設備幀頻可達80以上。

2、當縮放動畫碰上硬件加速

問題:

如下圖所示,如何平滑地實現底部導航的縮放呢?

1)、不能直接用scale來縮放,這樣會造成文字的縮放與虛化;

2)、不能通過 height的變化來更改高度,這樣不能啟用硬件加速。

解答:

需要分拆實現,高度變化用translateY來做,單獨對里面的圖標使用scale。

代碼:

nav{transition:.5s all ;} nav .icon{transition:.5s all;transform-origin:center bottom;} nav.mini{transform: translate(0, 50px);} nav.mini .icon{transform: scale(0.5, 0.5);}

3、動畫由Javascript來維護還是css維護的思考

近期制作的幾個動畫較多的網站,在動畫的調整與維護上花了不少時間,于是有了以下思考。

1)、判斷優劣維度

開發效率、維護、性能

2)、具體分析

a、由CSS維護。

實現:

結合transition和animation,將動畫時間軸寫死在CSS中。

開發效率:高。

結合現有配套工具,能夠快速完成動畫制作。

維護:差。

如果動畫涉及回調函數執行,時間軸同時存在于CSS與Javascript中,維護成本會大大提升。如果涉及判斷與循環,動畫效果將同時由CSS與Javascript來維護,代價太高。

性能:高。

動畫無需解析Javascript,減少DOM操作,性能較Javascript的方式更高。

b、由Javascript維護。

封裝動畫框架,底層調用CSS動畫,時間軸由Javascript來維護。

開發效率:高。無需考慮各平臺兼容性,配置參數即可完成動畫,對于復雜動畫,也可開發配套工具。

維護:好。動畫效果、動畫邏輯,全部由Javascript來維護,動畫可控性更高,維護變得很輕松。

性能:較高。由于底層還是調用CSS動畫,DOM操作次數有限,性能損耗并不會太高。

3)、總結。

對于弱交互,無邏輯的動畫,可以選用CSS的方式。對于復雜動畫,更推薦由Javascript來維護。

四、特性

1、如何解決音頻播放預加載與延時的問題

問題:

通過對各個平臺下進行音頻特性測試,存在問題如下:

IOS6 Android2.3 Android4.0
Audio標簽base64 不支持 不支持 不支持
預加載 不支持 支持 支持
自動播放 不支持 支持 支持
不同聲音同時播放 支持 支持 支持
播放延時
Web audio 支持 不支持 不支持

解決:

問題/平臺 IOS4-5 IOS6-7 Android2.3-4.2
預加載 不支持 Web?audio
(Base64->?ArrayBuffer)
Audio對象

代碼:

封裝類:

var lib = { _keyStr : "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=", decodeArrayBuffer: function(input) { var bytes = (input.length/4) * 3; var ab = new ArrayBuffer(bytes); this.decode(input, ab); return ab; }, decode: function(input, arrayBuffer) { var lkey1 = this._keyStr.indexOf(input.charAt(input.length-1)); var lkey2 = this._keyStr.indexOf(input.charAt(input.length-2)); var bytes = (input.length/4) * 3; if (lkey1 == 64) bytes--; if (lkey2 == 64) bytes--; var uarray; var chr1, chr2, chr3; var enc1, enc2, enc3, enc4; var i = 0; var j = 0; if (arrayBuffer) uarray = new Uint8Array(arrayBuffer); else uarray = new Uint8Array(bytes); input = input.replace(/[^A-Za-z0-9+/=]/g, ""); for (i=0; i<bytes; i+=3) { enc1 = this._keyStr.indexOf(input.charAt(j++)); enc2 = this._keyStr.indexOf(input.charAt(j++)); enc3 = this._keyStr.indexOf(input.charAt(j++)); enc4 = this._keyStr.indexOf(input.charAt(j++)); chr1 = (enc1 << 2) | (enc2 >> 4); chr2 = ((enc2 & 15) << 4) | (enc3 >> 2); chr3 = ((enc3 & 3) << 6) | enc4; uarray[i] = chr1; if (enc3 != 64) uarray[i+1] = chr2; if (enc4 != 64) uarray[i+2] = chr3; } return uarray; }, getScript: function(url, callback, charset){ var head = document.getElementsByTagName("head")[0] || document.documentElement, script = document.createElement("script"); script.src = url; charset && (script.charset = charset); script.onload = script.onreadystatechange = function() { if ((!this.readyState || this.readyState === "loaded" || this.readyState === "complete") ) { callback && callback(); script.onload = script.onreadystatechange = null; if (head && script.parentNode) head.removeChild(script); } }; head.appendChild(script); return script; } } var QAudio = function(config){ this.config = config; this.init(); } QAudio.prototype.init = function(){ var config = this.config; this.src = config.src; this.base64 = config.base64; if (\'AudioContext\' in window) { this.audioContext = new AudioContext(); } else if (\'webkitAudioContext\' in window) { this.audioContext = new webkitAudioContext(); } else { this.audio = document.createElement(\'audio\'); this.audio.preload = \'auto\'; this.audio.src = this.src; } // base64數據處理 if(this.audioContext) { this._handleBase64(); } this.load(); } QAudio.prototype._handleBase64 = function(){ var self = this; window[this.config.callback] = function(data){ var arrayBuff = lib.decodeArrayBuffer(data); self.audioContext.decodeAudioData(arrayBuff, function(audioData) { self._arrayBuff = audioData; }); } } QAudio.prototype.load = function(){ // 如果支持Web Audio,加載base64音頻 if(this.audioContext) { lib.getScript(this.base64); } else if(this.audio) { this.audio.load(); } } QAudio.prototype.play = function(){ if(this.audioContext) { var mySource = this.audioContext.createBufferSource(); mySource.buffer = this._arrayBuff; mySource.connect(this.audioContext.destination); if (\'AudioContext\' in window) { mySource.start(0); } else if (\'webkitAudioContext\' in window) { mySource.noteOn(0); } } else if(this.audio) { this.audio.play(); } } 

調用:

new QAudio({src: \'./audio/pop1.mp3\', base64: \'./audio/pop1.js\', callback: \'cbPop1\'});

示例:

2、重力感應

問題:

重力感應的實現相對簡單,具體見如下代碼。值得注意的是,android需3.0及以上才支持。

解決:

代碼:

var box = document.querySelector(\'.box\'); var timer; window.addEventListener(\'deviceorientation\', function(e) { var x = parseInt(e.gamma); var y = parseInt(e.beta); var r = parseInt(e.alpha); box.style.webkitTransform = \'translate3d(\' + x*window.innerWidth/180 + \'px, \'+ y*window.innerHeight/180 +\'px, 0) rotate(\'+ r +\'deg)\' }); 

3、啟動原生應用

背景:

在全民飛機大戰移動版的開發中,需要滿足一個需求,當用戶點擊下載按鈕時,如果用戶已經安裝了該APP,則直接啟動,否則跳到下載頁。

問題:

在網頁中如何啟動原生應用?

解決:

首先通過URL Scheme嘗試打開本地APP,如果打開成功,網頁中setTimeout將會掛起,重新回到頁面時超時不再執行,否則,如果打開失敗,則嘗試下載或進入下載頁面。

代碼:

(function(){ var iosURL = \'itms-apps://itunes.apple.com/cn/app/quan-min-fei-ji-da-zhan/id731871690?l=en&mt=8\'; var androidURL = \'http://dlied5.qq.com/wefly/release/android/1.0.5/wefly_1.0.5.6_android_8CF5F95E.apk\'; var iosScheme = \'tencentlaunch100539858:\'; var androidScheme = \'webwx47a71dd8a1875943:\'; var homePage = \'/web201404/\'; if(/iphone|ipod|ipad/i.test(navigator.userAgent)) { window.location = iosScheme; var startDate = new Date(); setTimeout(function(){ if(new Date() - startDate > 1000) return; window.location= iosURL; window.setTimeout(function(){ window.location= homePage; }, 100) } , 800); } else if(/android/i.test(navigator.userAgent)) { window.location = androidScheme; var startDate = new Date(); setTimeout(function(){ if(new Date() - startDate > 1000) return; window.location= androidURL; window.setTimeout(function(){ window.location= homePage; }, 1000) } , 800); } else { alert(\'非常抱歉,本游戲暫時只提供android和ios版。\'); window.location= homePage; } })(); 

4、地理定位 HTML 5 Geolocatioin

地理定位是HTML?5的重要熱性之一,它提供了用戶的確切位置(經緯度)。借助這個特性我們能夠開發基于地理位置的頁面。

HTML?5?Geolocatioin?API?使用起來很簡單,我們通過下面的方式調用。

ar x=document.getElementById("demo"); function getLocation(){ if (navigator.geolocation){ navigator.geolocation.getCurrentPosition(showPosition); }else{x.innerHTML="Geolocation is not supported by this browser.";} } function showPosition(position){ x.innerHTML="Latitude: " + position.coords.latitude + "<br />Longitude: " + position.coords.longitude; }

代碼邏輯是先判斷你的設備支不支持這個接口,進而給出相應的經緯度。結合TGA城市賽這個案例,我們可以通過用戶在訪問頁面的時候,獲取其經緯度,判斷用戶所在的城市,自動為其選中地址,減少操作步驟。如圖:

地址:

這里有一個小技巧,使用這個API我們只能獲取到經緯度,那怎么轉換成對應的具體地址呢?

1.?可以使用google的地圖API:

http://maps.google.com/maps/api/geocode/json?latlng=39.9,41.033&language=zh-CN&sensor=true

只要傳入正確的經緯度,就能夠返回相應的具體到街道的json數據。

2.?通過我們騰訊地圖的地址解析,可以做到具體地理位置字符跟經緯度的轉換。

http://open.map.qq.com/javascript_v2/case-run.html#sample-geocoding-simple。

五、其它

1、字體圖標應用設計環節的打通

問題:

字體圖標在這個項目中大量應用,但面臨的一個問題是,輔助前端開發的配套工具已經非常成熟,但設計環節的打通一直是一片空白。設計師在應用字體圖標時還是只能以最原始的方式將圖標拖入設計稿,十分不便。

解決:

為設計師提供一款Photoshop插件,將字體文件導入插件,設計師可以直接點擊圖標插入設計稿,將字體圖標應用的設計環節打通,該插件正在開發中。

2、當transform碰上模糊

問題:

如下圖ball1所示,在android中,如果元素或其父元素應用transform后,元素設置border-radius會變模糊。

解決:

將元素放大一倍后,再進行縮放(如果該元素后有文本節點,也可避免模糊)

body{padding: 20px;background:purple;-webkit-transform: translate3d(0px, 0px, 0px);} .ball1{width: 50px;height: 50px;border-radius:25px;margin-top: 20px;background: #fff;} .ball2{width: 100px;height: 100px;border-radius:50px;margin-top: 20px;background: #fff;-webkit-transform-origin:0 0;-webkit-transform: scale(0.5, 0.5);-webkit-backface-visibility:hidden;}

DEMO地址:

http://sy.qq.com/brucewan/feature/blur-radius.html

六、數據

1、用戶環境

從TGA移動游戲官網統計數據分析:

1)、抽樣50%訪問量統計,移動端用戶平均加速速度為70Kb/s;

2)、總加載時間為4.12s,86%的用戶愿意等待頁面加載完畢,52%的用戶抵達第二屏;

3)、這次滾屏支持用戶點擊游戲圖標或手指滑動,但只有7%的人會使用點擊操作,我們后續項目的設計中可以得到啟發。

 

為你的移動頁面尋找一絲新意——手機互動網頁項目總結(上)

本文鏈接:http://www.casaleticia.com/mobile-phone-webpage-project-summary-2.html
本文標簽: , , , , , , ,