移動端爬坑記 --- (1)佈局與樣式上的奇葩偶遇
阿新 • • 發佈:2019-02-05
前言
彙總下自己搞移動端遇到掉進去的坑,以及脫坑的方案;
Flex相容
Flex想要相容眾多花樣式手機,要注意以下這麼些
- 字首要考慮2009~2012年的語法[webkit-box,flex,flex-box]
- 少用複合屬性,比如
flex:1
,考慮相容理應拆成[flex-grow
,flex-shrink
,flex-basis
];flex-flow
拆開成[flex-direction
,flex-wrap
]
demo{
display: -webkit-box; /* OLD - iOS 6-, Safari 3.1-6 */
display : -moz-box; /* OLD - Firefox 19- (buggy but mostly works) */
display: -ms-flexbox; /* TWEENER - IE 10 */
display: -webkit-flex; /* NEW - Chrome */
display: flex; /* NEW, Spec - Opera 12.1, Firefox 20+ */
}
這些字首很少手動去寫,一般都用構建工具處理,我用的是gulp+autoprefixer來處理,這裡我的處理範圍
var AUTOPREFIXER_BROWSERS = [
'ie >= 9',
'ie_mob >= 9',
'ff >= 30',
'chrome >= 34',
'safari >= 7',
'opera >= 23',
'ios >= 7',
'android >= 2.3',
'bb >= 10'
];
值的一提的是,新增字首並不是萬能的,有些國內的手機就不吃這一套了,今天小夥伴就遇到了;華為的一款手機不支援常規的flex寫法。。。最終是原因是不能用行內元素,要改成block元素才能支援flex
2016-8-11 update: 使用flex:1的子元素,切記要增加width:0
% .. 有些android不帶這個很奇葩【錯亂】,且不要使用margin:0 auto【作用於子元素】
IOS的H5頁面scroll不流暢解決方案
在滾動包裹層新增這麼一條私有字首樣式即可享受類似APP的滑動效果,不僅絲滑,還帶彈性!
.contain{
-webkit-overflow-scrolling : touch;
}
IOS 遮罩層較好方案
拒絕採用fixed!!!!!
遮罩層採用position:absolute
來置頂,內部元素採用flex來佈局;
這種寫法可以避免一大堆天坑!!!
若是實在不信邪,滾動的時候,微信端這些你就會感受到花兒為什麼這樣紅了。。。
IOS滾動窗滑動到底部還能彈窗拖拉的奇葩修復
這個方案是通過計算離底部多遠加狀態來阻止touch事件
// 防止內容區域滾到底後引起頁面整體的滾動
var content = document.querySelector('main');
var startY;
content.addEventListener('touchstart', function (e) {
startY = e.touches[0].clientY;
});
content.addEventListener('touchmove', function (e) {
// 高位表示向上滾動
// 底位表示向下滾動
// 1容許 0禁止
var status = '11';
var ele = this;
var currentY = e.touches[0].clientY;
if (ele.scrollTop === 0) {
// 如果內容小於容器則同時禁止上下滾動
status = ele.offsetHeight >= ele.scrollHeight ? '00' : '01';
} else if (ele.scrollTop + ele.offsetHeight >= ele.scrollHeight) {
// 已經滾到底部了只能向上滾動
status = '10';
}
if (status != '11') {
// 判斷當前的滾動方向
var direction = currentY - startY > 0 ? '10' : '01';
// 操作方向和當前允許狀態求與運算,運算結果為0,就說明不允許該方向滾動,則禁止預設事件,阻止滾動
if (!(parseInt(status, 2) & parseInt(direction, 2))) {
e.preventDefault();
stopEvent(e);
}
}
});
ios和android下觸控元素時出現半透明灰色遮罩
/*E:這個是代指字元,實際自己替換,ID,CLASS,TAG*/
-webkit-tap-highlight-color:rgba(255,255,255,0)
IOS 預設輸入框內陰影重置
/*E:這個是代指字元,實際自己替換,ID,CLASS,TAG*/
E{
border: 0;
-webkit-appearance: none;
}
旋轉螢幕時,字型大小調整的問題
html, body, form, fieldset, p, div, h1, h2, h3, h4, h5, h6 {
-webkit-text-size-adjust:100%;
}
預設啟用GPU渲染頁面
這個具體要看你的實際作用範圍,無非就通過一些特殊屬性來強制開啟
- transform:translateZ(0)
: Z軸會啟用GPU,請自行帶字首
- 呼叫preserve-3d
或者animation
也會
transition閃屏
/設定內嵌的元素在 3D 空間如何呈現:保留3D /
-webkit-transform-style: preserve-3d;
/ 設定進行轉換的元素的背面在面對使用者時是否可見:隱藏 /
-webkit-backface-visibility:hidden;
placeholder的顏色值改變
input::-webkit-input-placeholder{color:#F40;}
input:focus::-webkit-input-placeholder{color:#F40;}
移動端禁止選中內容
E {
-webkit-user-select: none; /* Chrome all / Safari all */
-moz-user-select: none; /* Firefox all (移動端不需要) */
-ms-user-select: none; /* IE 10+ */
}
IOS禁止儲存或拷貝影象
img { -webkit-touch-callout: none; }
常用的移動端meta
<!-- 禁止頁面縮放 -->
<meta name="viewport" content="width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=0" />
<!-- 設定Web應用是否以全屏模式執行。-->
<meta name="apple-mobile-web-app-capable" content="yes">
<!-- 啟動或禁用自動識別頁面中的電話號碼。-->
<meta name="format-detection" content="telephone=no">
<!-- 設定快取,看實際需求設定 -->
<meta http-equiv="Cache-Control" content="no-cache" />
<!-- 優先使用最新版本 IE 和 Chrome-->
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
<!-- QQ瀏覽器私有 -->
<!-- 全屏模式 -->
<meta name="x5-fullscreen" content="true">
<!-- 強制豎屏 -->
<meta name="x5-orientation" content="portrait">
<!-- 強制橫屏 -->
<meta name="x5-orientation" content="landscape">
<!-- 應用模式 -->
<meta name="x5-page-mode" content="app">
<!-- UC瀏覽器私有 -->
<!-- 全屏模式 -->
<meta name="full-screen" content="yes">
<!-- 強制豎屏 -->
<meta name="screen-orientation" content="portrait">
<!-- 強制橫屏 -->
<meta name="screen-orientation" content="landscape">
<!-- 應用模式 -->
<meta name="browsermode" content="application">
IOS中input鍵盤事件呼叫緩慢
直接改為監聽input事件
document.getElementById('test').addEventListener('input',fn,false);
頁面高度渲染錯誤
document.documentElement.style.height = window.innerHeight + 'px';
怪異懸浮的表單
在部分android 機型中的輸入框可能會出現如圖怪異的多餘的浮出表單,經過觀察與測試發現只有input:password型別的輸入框存在,那麼我們只要使用input:text型別的輸入框並通過樣式-webkit-text-security: disc; 隱藏輸入密碼從而解決。
input[type=text]{
-webkit-text-security: disc;
}
其他一些建議
- 能用transform實現的過渡的,可以不考慮animation實現;animation在部分機子過渡非常掉幀,體驗非常糟糕,,遇到過好幾次
- 頁面有滾動區域的建議引入iscroll5,可以避免很多天坑
- 頁面應該儘可能的減少複雜的DOM【一個功能點,DOM結構越直白,越好維護】,複雜DOM會增加維護難度
- 考慮移動端響應佈局,建議引入阿里巴巴出品的lib-flexible , IOS動態調整DPR,其他裝置預設DPR1
- 點透事件可以引入fastclick或者不用click,改為touch來寫,亦或者引入zepto的tap事件
若是以後還有遇到哪些奇葩坑,爬出來了會繼續更新此帖子