移動(dòng)端開(kāi)發(fā)必須知道的小技巧(轉(zhuǎn)) app項(xiàng)目
電腦知識(shí) 由小雪供稿前言
最近在公司寫(xiě)一個(gè)混合 app 項(xiàng)目,頁(yè)面基本全部都是用 H5 完成,嵌入到原生 webview 下。發(fā)現(xiàn)一個(gè)問(wèn)題,在 iPhone 6 下 蘋(píng)果手機(jī)的狀態(tài)欄會(huì)擋住頁(yè)面,導(dǎo)致頁(yè)面下移,樣式錯(cuò)亂,最后網(wǎng)上查找了些解決辦法,加了一條 meta 標(biāo)簽解決了問(wèn)題。今天特來(lái)總結(jié)下常用的移動(dòng)端開(kāi)發(fā)需要注意的meta標(biāo)簽及一些小技巧。
- viewport
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0">
這個(gè)是移動(dòng)端頁(yè)面開(kāi)發(fā)必備的標(biāo)簽,用來(lái)調(diào)整布局視口同視覺(jué)視口一致,禁止頁(yè)面縮放等。
apple-mobile-web-app-capable
apple-mobile-web-app-capable
是設(shè)置 Web 應(yīng)用是否以全屏模式運(yùn)行。
語(yǔ)法:
<meta name="apple-mobile-web-app-capable" content="yes">
說(shuō)明:
如果 content 設(shè)置為yes,Web應(yīng)用會(huì)以全屏模式運(yùn)行,反之,則不會(huì)。content的默認(rèn)值是no,表示正常顯示。如果選擇全屏模式運(yùn)行,則會(huì)刪除默認(rèn)的蘋(píng)果工具欄和菜單欄。
我開(kāi)篇遇到的問(wèn)題就是通過(guò)設(shè)置該 meta 標(biāo)簽解決的。
- 設(shè)置頂部狀態(tài)欄的顏色
<meta name="apple-mobile-web-app-status-bar-style" content="black" />
說(shuō)明:
這個(gè)標(biāo)簽起作用的前提是 必須事先開(kāi)啟了全屏模式運(yùn)行 webapp,即 第二條的 meta 標(biāo)簽必須同步指定,否則這個(gè)標(biāo)簽不起作用。
如果content設(shè)置為default,則狀態(tài)欄正常顯示。如果設(shè)置為blank,則狀態(tài)欄會(huì)有一個(gè)黑色的背景。如果設(shè)置為blank-translucent,則狀態(tài)欄顯示為黑色半透明。如果設(shè)置為default或blank,則頁(yè)面顯示在狀態(tài)欄的下方,即狀態(tài)欄占據(jù)上方部分,頁(yè)面占據(jù)下方部分,二者沒(méi)有遮擋對(duì)方或被遮擋。如果設(shè)置為blank-translucent,則頁(yè)面會(huì)充滿屏幕,其中頁(yè)面頂部會(huì)被狀態(tài)欄遮蓋?。〞?huì)覆蓋頁(yè)面20px高度,而iphone4和itouch4的Retina屏幕為40px)。默認(rèn)值是default。
- webapp添加到主屏后的標(biāo)題(iOS 6 新增)
<meta name="apple-mobile-web-app-title" content="title">
- 設(shè)置緩存
<meta http-equiv="Cache-Control" content="no-cache" />
手機(jī)頁(yè)面通常在第一次加載后會(huì)進(jìn)行緩存,然后每次刷新會(huì)使用緩存而不是去重新向服務(wù)器發(fā)送請(qǐng)求。如果不希望使用緩存可以設(shè)置no-cache。
- format-detection
format-detection 啟動(dòng)或禁用自動(dòng)識(shí)別頁(yè)面中的電話號(hào)碼。
語(yǔ)法:
<meta name="format-detection" content="telephone=no">
說(shuō)明:
默認(rèn)情況下,設(shè)備會(huì)自動(dòng)識(shí)別任何可能是電話號(hào)碼的字符串。設(shè)置telephone=no可以禁用這項(xiàng)功能。
- html5調(diào)用安卓或者ios的撥號(hào)功能
html5提供了自動(dòng)調(diào)用撥號(hào)的標(biāo)簽,只要在a標(biāo)簽的href中添加tel:就可以了。
撥打手機(jī)直接如下:
<a href="tel:15677776767">點(diǎn)擊撥打15677776767</a>
PS:如果遇到這種情況失效,可以在頁(yè)面頭部 添加 上一條meta 標(biāo)簽,content 設(shè)置為 yes。
- iphone及ipad下輸入框默認(rèn)出現(xiàn)內(nèi)陰影。
Element{
-webkit-appearance: none;
}
- 移動(dòng)端滑動(dòng)頁(yè)面絕對(duì)定位元素出現(xiàn)抖動(dòng)
這個(gè)問(wèn)題自己網(wǎng)上找了一些解決辦法,僅供參考。
- 給body設(shè)置高度100%
body,html{
widht:100%;
height:100%;
}
如果是項(xiàng)目中已經(jīng)做好的頁(yè)面,有其他特效,直接設(shè)置這個(gè)屬性,可能對(duì)頁(yè)面的其他功能造成影響。
如果使用此法,本地調(diào)試效果不好,建議不要使用。
- 給固定定位的元素添加transform屬性
transform:translateZ(0);
或者transform:translate3d(0,0,0);
- 外層嵌套一個(gè)盒子
多加一層盒子,外層fixed固定定位,內(nèi)層的設(shè)置絕對(duì)定位absolute;
<div style='position: fixed;'>
<div style='position: absolute'>
...
</div>
</div>
- iphone下 input 框光標(biāo)過(guò)長(zhǎng)
input 輸入框在 iPhone 下 光標(biāo)過(guò)長(zhǎng),Android顯示正常。
方法:
調(diào)低 input 標(biāo)簽的 line-height 樣式值。
- ios 下 頁(yè)面滑動(dòng)卡頓,不流暢
在內(nèi)容出現(xiàn)滾動(dòng)的元素上設(shè)置一條css樣式,實(shí)現(xiàn)慣性滾動(dòng)和彈性效果。
{
-webkit-overflow-scrolling: touch;
}
-webkit-overflow-scrolling
屬性控制元素在移動(dòng)設(shè)備上是否使用滾動(dòng)回彈效果,它有兩個(gè)值:
auto
: 使用普通滾動(dòng), 當(dāng)手指從觸摸屏上移開(kāi),滾動(dòng)會(huì)立即停止。
touch
:
使用具有回彈效果的滾動(dòng), 當(dāng)手指從觸摸屏上移開(kāi),內(nèi)容會(huì)繼續(xù)保持一段時(shí)間的滾動(dòng)效果。繼續(xù)滾動(dòng)的速度和持續(xù)的時(shí)間和滾動(dòng)手勢(shì)的強(qiáng)烈程度成正比。同時(shí)也會(huì)創(chuàng)建一個(gè)新的堆棧上下文。
- 頁(yè)面頂部固定定位元素或底部固定定位元素遮擋頁(yè)面部分內(nèi)容。
方法一:
給最外層的div加上 padding-bottom
, 值為 固定定位元素高度;
方法二:
利用偽元素,給最外層div添加偽元素 after,設(shè)置高度為 固定定位元素高度。
.wrapper::after{
content: '';
height: '固定定位元素高度';
}
- 禁止復(fù)制、選中文本
Element {
-webkit-user-select: none;
-moz-user-select: none;
-khtml-user-select: none;
user-select: none;
}
- IOS中input鍵盤(pán)事件keyup、keydown、keypress支持不是很好
用input search做模糊搜索的時(shí)候,在鍵盤(pán)里面輸入關(guān)鍵詞,會(huì)通過(guò)ajax后臺(tái)查詢,然后返回?cái)?shù)據(jù),然后再對(duì)返回的數(shù)據(jù)進(jìn)行關(guān)鍵詞標(biāo)紅。用input監(jiān)聽(tīng)鍵盤(pán)keyup事件,在安卓手機(jī)瀏覽器中是可以的,但是在ios手機(jī)瀏覽器中變紅很慢,用輸入法輸入之后,并未立刻相應(yīng)keyup事件,只有在通過(guò)刪除之后才能相應(yīng)!
解決辦法:
可以用html5的oninput事件去代替keyup
<input type="text" id="test">
<script type="text/javascript">
document.getElementById('test').addEventListener('input', function(e){
var value = e.target.value
....
})
</script>
然后就達(dá)到類(lèi)似keyup的效果!
- webview 下部分 JavaScript 代碼沒(méi)有執(zhí)行,比如 alert()等。
解決辦法:
webview只是一個(gè)承載體、各種內(nèi)容的渲染需要使用webviewChromClient去實(shí)現(xiàn)、所以set一個(gè)默認(rèn)的基類(lèi)WebChromeClient就行。
PS:這部分需要原生開(kāi)發(fā)協(xié)助設(shè)置一個(gè) 基類(lèi) WebChromeClient,代碼:
WebView.setWebChromeClient()
- 移動(dòng)端點(diǎn)擊300ms延遲
300ms 尚可接受,不過(guò)因?yàn)?00ms產(chǎn)生的問(wèn)題,我們必須要解決。300ms導(dǎo)致用戶體驗(yàn)并不是很好,解決這個(gè)問(wèn)題,我們一般在移動(dòng)端用 tap 事件來(lái)取代click 事件。
推薦兩個(gè) js,一個(gè)是 fastclick
,一個(gè)是 tap.js
。
關(guān)于移動(dòng)端點(diǎn)擊延遲處理方案,詳細(xì)敘述請(qǐng)看:移動(dòng)端點(diǎn)擊延遲處理方案
- 移動(dòng)端點(diǎn)擊穿透問(wèn)題
案例如下:
<div id="haorooms">點(diǎn)透事件測(cè)試</div>
<a href="http://www.inspiredelm.com">9252兒童網(wǎng)</a>
div是絕對(duì)定位的蒙層, 并且z-index高于a。而a標(biāo)簽是頁(yè)面中的一個(gè)鏈接,我們給div綁定tap事件:
$('#haorooms').on('tap',function(){
$('#haorooms').hide()
})
我們點(diǎn)擊蒙層時(shí) div正常消失,但是當(dāng)我們?cè)赼標(biāo)簽上點(diǎn)擊蒙層時(shí),發(fā)現(xiàn)a鏈接被觸發(fā),這就是所謂的點(diǎn)透事件。
原因:
touchstart 早于 touchend 早于click。 亦即click的觸發(fā)是有延遲的,這個(gè)時(shí)間大概在300ms左右,也就是說(shuō)我們tap觸發(fā)之后蒙層隱藏, 此時(shí) click還沒(méi)有觸發(fā),300ms之后由于蒙層隱藏,我們的click觸發(fā)到了下面的a鏈接上。
解決辦法:
- 盡量都使用 touch 事件來(lái)替換click事件。例如用touchend事件(推薦)。
-
用 fastclick,詳情看上面 GitHub 倉(cāng)庫(kù)。
-
用preventDefault阻止a標(biāo)簽的click。
-
延遲一定的時(shí)間(300ms+)來(lái)處理事件 (不推薦)。
-
以上一般都能解決,實(shí)在不行就換成click事件。
下面介紹一下touchend事件,如下:
$("#haorooms").on("touchend", function (event) {
event.preventDefault()
})
- iOS中,中文輸入法輸入英文時(shí),字母之間可能會(huì)出現(xiàn)一個(gè)六分之一空格
可以通過(guò)正則去掉
this.value = this.value.replace(/\u2006/g, '')
- 解決 iOS 中 video 標(biāo)簽視頻自動(dòng)全屏播放問(wèn)題
給 video 標(biāo)簽添加 屬性:
<!-- 針對(duì) iOS8,9下生效 -->
<video webkit-playsinline="webkit-playsinline"></video>
<!-- ios10 及以上 -->
<video playsinline="playsinline"></video>
PS: 如果是內(nèi)嵌入 webview 下 還需要原生開(kāi)發(fā)的伙伴添加以下支持代碼:
webView.allowsInlineMediaPlayback = YES;
- 移動(dòng)端點(diǎn)擊鏈接發(fā)送郵件
<a href="mailto:pubdreamcc@qq.com?subject=TestObject">pubdreamcc@qq.com</a>
點(diǎn)擊后直接給 pubdreamcc@qq.com 發(fā)郵件,主題為:TestObject 。
PS: 如果遇到這種情況失效,可以在頁(yè)面頭部 添加 一條meta 標(biāo)簽,content 設(shè)置為 yes。
<meta name="format-detection" content="email=yes">
- 移動(dòng)端滾動(dòng)穿透
描述:
在打開(kāi)的彈窗或者遮罩層上滾動(dòng), 會(huì)影響到下層的body元素的滾動(dòng)。 體驗(yàn)很不好。
解決辦法:
一般思路是在打開(kāi)彈框或遮罩層的時(shí)候,獲取html的scrollTop, 給body改為fixed定位, top值為負(fù)的scrollTop值。 關(guān)閉彈框的時(shí)候,把fixed定位去掉。還原scrollTop值。
- 移動(dòng)端布局方式
這個(gè)基本是我們做移動(dòng)開(kāi)發(fā)首先需要確定的一個(gè)方案,我總結(jié)為一句話:
經(jīng)典的 REM 布局與新秀 VW 布局
當(dāng)然還有常見(jiàn)的比如 彈性盒子(flex) 都可以。
不過(guò)需要說(shuō)的是,淘寶 flexible.js 布局的作者已經(jīng)推薦我們選用 vw 布局。
這部分大家可以自己網(wǎng)上查閱相關(guān)資料,我這里就不多做累述了。