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

目錄:javascript

1、項目地址css

2、佈局
一、按屏滾動會碰到什麼問題?
二、flexbox會碰到什麼問題?
三、fixed定位須要慎用。
html

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

4、特性
一、如何解決音頻播放預加載與延時的問題
二、重力感應
三、啓動原生應用
四、地理定位
java

5、其它
一、字體圖標應用設計環節的打通
二、當transform碰上模糊
android

6、數據
一、用戶環境ios

1、項目地址git

一、TGA移動遊戲官網web

TGA城市拉力賽json

 

二、UP+邀請函

三、每天酷跑里約進擊版

2、佈局

一、按屏滾動會碰到什麼問題?

問題:

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

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();
});

二、flexbox會碰到什麼問題?

問題:

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

解決:

須要將子元素設爲絕對定位。

三、fixed定位須要慎用。

問題:

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

解決:

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

3、動畫

一、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以上。

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

問題:

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

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);}

三、動畫由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來維護。

4、特性

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

問題:

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

 

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'});

示例:

二、重力感應

問題:

重力感應的實現相對簡單,具體見以下代碼。值得注意的是,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)'
});

三、啓動原生應用

背景:

在全民飛機大戰移動版的開發中,須要知足一個需求,當用戶點擊下載按鈕時,若是用戶已經安裝了該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;
	}

})();

四、地理定位 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。

5、其它

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

問題:

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

解決:

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

二、當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

6、數據

一、用戶環境

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

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

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

3)、此次滾屏支持用戶點擊遊戲圖標或手指滑動,但只有7%的人會使用點擊操做,咱們後續項目的設計中能夠獲得啓發。

 

來源轉載:http://tgideas.qq.com/webplat/info/news_version3/804/808/811/m579/201404/258325.shtml

相關文章
相關標籤/搜索