移動端H5頁面開發坑點指南

資料鏈接 https://mp.weixin.qq.com/s/ExS2gRGY5zFXF_vh0riLSA

一、canvas在retina屏模糊

只需要將畫筆根據像素比縮放即可

run(canvasEl) {
    const canvas = canvasEl;
    const ctx = canvas.getContext('2d');
    const devicePixelRatio = window.devicePixelRatio || 1;
    const backingStorePixelRatio = ctx.webkitBackingStorePixelRatio ||
    ctx.mozBackingStorePixelRatio ||
    ctx.msBackingStorePixelRatio ||
    ctx.oBackingStorePixelRatio ||
    ctx.backingStorePixelRatio || 1;

    const ratio = devicePixelRatio / backingStorePixelRatio;
    if (devicePixelRatio !== backingStorePixelRatio) {
      const oldWidth = canvas.width;
      const oldHeight = canvas.height;

      canvas.width = oldWidth * ratio;
      canvas.height = oldHeight * ratio;

      canvas.style.width = `${oldWidth}px`;
      canvas.style.height = `${oldHeight}px`;
      ctx.scale(ratio, ratio);
    }
  },

二、 用同等比例的圖片在PC機上很清楚,但是手機上很模糊,原因是什么呢?

經研究發現是devicePixelRatio作怪,因為手機分辨率太小,如果按照分辨率來顯示網頁字會非常小,所以蘋果就把iPhone 4的960640分辨率在網頁里只顯示了480320,這樣devicePixelRatio=2;現在android比較亂,有1.5/2/3等,想讓圖片在手機里顯示更為清晰必須使用2x的背景圖來代替img標簽(一般情況都是用2倍),例如一個div的寬高是100100,背景圖必須得200200,然后background-size:contain;,這樣顯示出來的圖片就比較清晰了;代碼如下:

   background:url(../images/icon/all.png) no-repeat center center;
   -webkit-background-size:50px 50px;
   background-size: 50px 50px;
   display:inline-block; 
   width:100%; 
   height:50px;

三、啟動或禁用自動識別頁面中的電話號碼;

<meta name="format-detection" content="telephone=no">

默認情況下設備會自動識別任何可能是電話號碼的字符串,設置telephone=no可以禁用這項功能,設置不識別郵箱和地址也同理

四、h5網站input設置為type=number的問題

h5網頁input的type設置為number一般會產生三個問題:

問題1:maxlength屬性不好用

<input type="number" oninput="checkTextLength(this ,10)">
<script type="text/javascript">
    function checkTextLength(obj, length) {
        if(obj.value.length > length)  {
            obj.value = obj.value.substr(0, length);
        }
    }
</script>

問題2:form提交的時候默認取整

<input type="number" step="0.01" /> 
/** input中type=number一般會自動生成一個上下箭頭,點擊上箭頭默認增加一個step,
點擊下箭頭默認會減少一個step;number中默認step是1,也就是step=0.01可以允許輸入2位小數,并且
點擊上下箭頭分別增加0.01和減少0.01;step和min一起使用時數值必須在min和max之間 */

問題3:部分安卓手機出現樣式問題

去除input默認樣式的方法:

input,textarea {
    border: 0;
    -webkit-appearance: none; 
/**可同時屏蔽輸入框怪異的內陰影,解決iOS下無法修改按鈕樣式,
測試還發現,加了此屬性后,iOS下默認還是有圓角的,
不過可以用border-radius屬性修改*/
}

五、select下拉選擇設置問題

問題1:右對齊實現

設置如下屬性

select option {
    direction: rtl;
}

問題2:禁用select默認箭頭

::-ms-expand修改表單控件下拉箭頭,設置隱藏并使用背景圖片來修飾

select::-ms-expand { display:none; }

六、移動端HTML5 audio autoplay失效問題

由于自動播放網頁中的音頻或視頻會給用戶帶來困擾或不必要的流量消耗,所以蘋果系統和安卓系統通常都會禁止自動播放和使用JS的觸發播放,必須由用戶來觸發才播放;解決方法思路:先通過用戶touchstart觸碰觸發播放并暫停(讓音頻開始加載),后面用JS再操作就沒問題了;解決代碼:

document.addEventListener('touchstart', function () {
    document.getElementsByTagName('audio')[0].play();
    document.getElementsByTagName('audio')[0].pause();
});

七、CSS動畫頁面閃白,動畫卡頓,圖片錯亂的問題

1.盡可能地使用合成屬性transform和opacity來設計CSS3動畫,不使用position的left和top來定位
2.開啟硬件加速

-webkit-transform: translate3d(0, 0, 0);
-moz-transform: translate3d(0, 0, 0);
-ms-transform: translate3d(0, 0, 0);
transform: translate3d(0, 0, 0);

八、浮動子元素撐開父元素盒子高度(BFC)

解決方法如下:

1.父元素設置為 overflow: hidden;

2.父元素設置為 display: inline-block;等

這里兩種方法都是通過設置css屬性將浮動元素的父元素變成BFC(塊級格式化上下文)元素,使子元素高度可以撐開父元素;不過最好使用方法1,因為inline-block元素本身會自帶一些寬高度撐開其本身。

九、往返緩存問題

點擊瀏覽器的回退有時候不會自動執行js,特別是在mobilesafari中;這與往返緩存(bfcache)有關系,解決方法:

window.onunload = function(){};

十、定位的坑

在IOS下fixed定位在軟鍵盤頂起時會失效,所以我們在開發時統一使用absolute代替

十一、audio元素和video元素在ios和andriod中播放問題

<audio src="music/bg.mp3" autoplay loop controls>你的瀏覽器還不支持哦</audio> //音頻,寫法一
<audio controls="controls"> //音頻,寫法二   
    <source src="music/bg.ogg" type="audio/ogg"></source>
    <source src="music/bg.mp3" type="audio/mpeg"></source> 
//優先播放音樂bg.ogg,不支持在播放bg.mp3    
</audio>

到這里一般都可以播放音樂了,如果還不行很有可能是微信的限制。
如果是微信的限制,這時需要調用微信接口,

  1. 頁面先引入:
<script src="http://res.wx.qq.com/open/js/jweixin-1.0.0.js"></script>

2)然后JS寫入微信事件:

document.addEventListener("WeixinJSBridgeReady", function() {
    document.getElementById('music').play();
}, false);

小結:

1.audio元素的autoplay屬性在IOS及Android上無法使用,在PC端正常

2.audio元素沒有設置controls時,在IOS及Android會占據空間大小,而在PC端Chrome是不會占據任何空間

Safari瀏覽器自動播放


document.addEventListener('touchstart', function(){   
    audio.play();
}, false);

十二、ios系統不支持動畫暫停樣式(animation-play-state)

H5頁面一般都會有BGM,也會提供一個旋轉的音樂圖標供用戶開啟關閉音樂;我們希望當用戶點擊音樂按鈕時圖標停止旋轉,再點圖標順著之前停止的位置繼續跑動畫;animation-play-state是最簡便的方式,然而ios不支持。

目前的解決方案是:音樂圖標負責跑動畫,圖標父級元素負責記錄停止時的轉動值。

十三、ios防止長按頁面元素被選中

解決方案: 加入樣式可禁止用戶進行復制,ios和一般的安卓都可以解決

-webkit-touch-callout:none;  //系統默認菜單被禁用;可以實現頁面因為長按彈出各種操作窗口
-webkit-user-select:none; //webkit瀏覽器  
-khtml-user-select:none; //早期瀏覽器 
-moz-user-select:none; //火狐 
-ms-user-select:none; //IE10 
user-select:none; 

添加完這段代碼后在IOS上會有問題,這時發現input框無法正常輸入內容了;造成這個原因是-webkit-user-select:none;這個屬性,解決方法就是在css文件中同時設置一下input的屬性,如下:

input {      
     -webkit-user-select:auto; //webkit瀏覽器    
}

十四、html5碰到上下拉動滾動條時卡頓/慢怎么解決

首先你可能會給頁面的html和body增加了height: 100%, 然后就可能造成IOS上頁面滑動的卡頓問題。
解決方案:

1.讓html和body固定100%(或者100vh);

2.然后再在內部放一個height:100%的div,設置overflow-y: auto;和-webkit-overflow-scrolling: touch。

overflow-x:auto在iOS有兼容問題,解決方法:

.scroll-box {
  /* 模態框之類的div不能放在這個容器中,否則關閉模態框有時候關閉不了 */
  height: 100%;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  overflow-scrolling: touch;
}

十五、點擊元素產生背景或邊框怎么去掉

a,button,input,textarea{ 
  -webkit-tap-highlight-color: rgba(0,0,0,0); 
  -webkit-user-modify: read-write-plaintext-only; //-webkit-user-modify有個副作用,就是輸入法不再能夠輸入多個字符 
} 
//或 
a,button,input,textarea{ 
  -webkit-tap-highlight-color: rgba(0,0,0,0); 
}

十六、瀏覽器后退不刷新

這種情況是以前遇到的,這里也說下;主要會發生在webview里多一點,當點擊后退時頁面以緩存形式出現,而不是刷新后的,很多情況下這不是你預期的效果,解決方法是用js:

// 方法1:
window.addEventListener('pageshow', () => {
  if (e.persisted || (window.performance && 
    window.performance.navigation.type == 2)) {
    location.reload()
  }
}, false);

// 方法2:
window.history.replaceState(null, '', 
    window.location.href + '?timestamp=' + new Date().getTime());

onpageshow每次頁面加載都會觸發,無論是從緩存中加載還是正常加載,這是他和onload的區別;persisted判斷頁面是否從緩存中讀出

頁面通過歷史記錄和前進后退訪問時。type值為2

十七、transition清除閃屏

-webkit-transform-style: preserve-3d; //設置內嵌的元素在 3D 空間如何呈現:保留3D
-webkit-backface-visibility:hidden; //設置進行轉換的元素的背面在面對用戶時是否可見:隱藏
-webkit-perspective: 1000;

十八、解決active偽類失效

<body ontouchstart></body>

十九、頂部狀態欄背景色

apple-mobile-web-app-capable是設置Web應用是否以全屏模式運行;語法:

<meta name="apple-mobile-web-app-capable" content="yes">
 //content設置為yes, Web應用會以全屏模式
<meta name="apple-mobile-web-app-status-bar-style" content="black" />

說明:除非你先使用apple-mobile-web-app-capable指定全屏模式,否則這個meta標簽不會起任何作用;如果content設置為default,則狀態欄正常顯示;如果設置為blank,則狀態欄會有一個黑色的背景;如果設置為blank-translucent,則狀態欄顯示為黑色半透明;如果設置為default或blank,則頁面顯示在狀態欄的下方,即狀態欄占據上方部分;頁面占據下方部分,二者沒有遮擋對方或被遮擋;如果設置為blank-translucent,則頁面會充滿屏幕,其中頁面頂部會被狀態欄遮蓋住(會覆蓋頁面20px高度,而iphone4和itouch4的Retina屏幕為40px);默認值是default。

ios專區

二十、IOS中對input鍵盤事件keyup/keydown/keypress等支持不好的問題

經查發現,IOS的輸入法(不管是第三方還是自帶)能檢測到英文或數字的keyup,但檢測不到中文的keyup,在輸入中文后需要點回退鍵才開始搜索;解決辦法是用html5的oninput事件去代替keyup,通過如下代碼達到類似keyup的效果;

1.修改了input:checkbox或input:radio元素的選擇中狀態,checked屬性發生變化
2.修改了input:text或textarea元素的值,value屬性發生變化
3.修改了select元素的選中項,selectedIndex屬性發生變化 統一使用input監聽

<input type="text" id="testInput">
<script type="text/javascript">
    document.getElementById('testInput').addEventListener('input', function(e){
        var value = e.target.value;
 //e.target指向事件執行時鼠標所點擊區域的那個元素;初學者會認為
//當前事件所綁定的元素就是鼠標所點擊的那個元素,
// 這時就要看看實際綁定的元素內部有沒有子元素,如果有e.target指向這個子元素,
//如果沒有e.target和this都指向事件所綁定的元素
    });
</script>

二十一、IOS鍵盤字母輸入,默認首字母大寫的解決方案

設置如下屬性

<input autocapitalize="off" autocorrect="off" />

input的三個屬性:

  • autocomplete:默認為on,代表是否讓瀏覽器自動記錄輸入的值,可以在input中加入autocomplete="off"來關閉記錄,保密輸入內容;
  • autocapitalize:自動大小寫;
  • autocorrect:糾錯

二十二、關于iOS與OS X端字體的優化(橫豎屏會出現字體加粗不一致等)問題

iOS瀏覽器橫屏時會重置字體大小,設置text-size-adjust為none可以解決iOS上的問題,但桌面版Safari的字體縮放功能會失效,因此最佳方案是將text-size-adjust為100%

-webkit-text-size-adjust: 100%;
-ms-text-size-adjust: 100%;
text-size-adjust: 100%;

二十三、某些情況下非可點擊元素如(label,span)監聽click事件,ios下不會觸發

cursor: pointer;

二十四、ios對時間date()的支持不一樣

var date =new Date("2019/10/21");

調試發現2019/10/21等同2019-10-21 00:00:00,也就是說ios默認就是從0開始計算的,我們不需要設置后面的時分秒為00:00:00

二十五、iOS(safari)標簽綁定點擊事件無效

iOS(safari)有時候某個標簽綁定點擊事件無效,加上空的onclick=""就好了,如:<a onclick=""></a>

二十六、ios中location.href跳轉頁面空白

在location.href外套一層setTimeout就解決了!

setTimeout(() => {
       window.location.href = 'www.juejin.im'
}, 0);

二十七、鍵盤彈起下落時的bug解決方法

在App.vue的created鉤子里統一處理即可


created() {
    this.handleFocusOut();
    this.handleResize();
},
methods:{
    handleFocusOut() {
      /** input 焦點失焦后,ios 鍵盤收起,
         但沒有觸發 window resize,導致實際頁面dom仍然被鍵盤頂上去--錯位*/
      document.addEventListener('focusout', () => {
        document.body.scrollTop = 0;
      });
    },
    /** 監聽resize事件(鍵盤彈起觸發),
然后將 input textarea 元素滑動到可視區域,并將特定元素隱藏*/
    handleResize() {
      const clientHeight = document.documentElement.clientHeight;
      window.addEventListener('resize', () => {
        // 判斷當前 active 的元素是否為 input 或 textarea
        if (
          document.activeElement.tagName === 'INPUT' ||
          document.activeElement.tagName === 'TEXTAREA'
        ) {
          setTimeout(() => {
            // 原生方法,滾動至需要顯示的位置
            document.activeElement.scrollIntoView();
          }, 0);
        }

        // 解決鍵盤彈起后 fixed 定位元素被頂起問題
        const bodyHeight = document.documentElement.clientHeight;
        const ele = document.getElementById('fixed-bottom');
        if (ele) {
          if (clientHeight > bodyHeight) {
            ele.style.display = 'none';
          } else {
            ele.style.display = 'block';
          }
        }
      });
    }
}
?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 227,702評論 6 531
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,143評論 3 415
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 175,553評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,620評論 1 307
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,416評論 6 405
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 54,940評論 1 321
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,024評論 3 440
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,170評論 0 287
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,709評論 1 333
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,597評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,784評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,291評論 5 357
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,029評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,407評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,663評論 1 280
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,403評論 3 390
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,746評論 2 370

推薦閱讀更多精彩內容