移動端常見相容性問題解決方案

程式設計師大白發表於2018-08-10

audio

  • audio無法自動播放(ios考慮到使用者體驗問題,限制audio必須在使用者主動互動之後才能夠播放) 解決方案:提前建立audio標籤,使用者互動之後觸發自動播放
//--建立觸控監聽,當瀏覽器開啟頁面時,觸控螢幕觸發事件,進行音訊播放
document.addEventListener('touchstart', function () {
    var audio = document.getElementById('audio');
        audio.play();
});
複製程式碼
  • ios下audio只能播放一遍,再次play無法繼續播放
    解決方案:play()前先load()下
var clickAudio = null;

// 播放點選音效
function playClickMusic() {
    if (!clickAudio) {
      clickAudio = $('#click')[0];
    }
    clickAudio.load();
    clickAudio.play();
}
複製程式碼
  • ios自帶輸入法輸入中文連續觸發多次input事件
    解決方案:利用compositionstart和compositionend事件作為開關,中文輸入結束才觸發input事件,程式碼如下,詳見ios自帶輸入法觸發多次input解決方案
var flag = false;
$('#id').on({
    'compositionstart': function() {
      flag = true;
    },
    'compositionend': function() {
      flag = false;
      if(!flag) {
        //do something...
        doSomethingFunction();
      }
    },
    'input propertychange': function() {
        if(!flag) {
          //do something...
          doSomethingFunction();
        }
    }
});
複製程式碼

video

  • 頁面內播放
    解決方案:給video標籤新增playsinline屬性
<video src="" webkit-playsinline playsinline x5-playsinline></video>
複製程式碼

注:x5核心-安卓下不能新增airplay="allow" x5-video-player-fullscreen="true" x-webkit-airplay="allow"(新增了之後playsinline屬性就失效了)

x5核心video api:騰訊x5核心api文件中的video部分

  • ios下視訊無法播放常見原因

1、若視訊是MP4格式則必須是h264編碼
2、視訊資源必須支援分片傳輸(非分片傳輸的話在safari中不能播放)

視訊檔案分片傳輸參考:nginx檔案分片傳輸配置

其他

  • click事件有延遲(原因:客戶端瀏覽器一般雙擊可放大頁面,瀏覽器在檢測到第一次click事件時不會馬上觸發,一般會等到300ms後無下一次click事件後才會觸發click事件)
    解決方案:fastclick

  • 微信下長按儲存圖片(微信下不支援通過為a標籤新增download屬性直接下載圖片)
    解決方案:先用html2canvas將dom繪製在canvas上,然後使用絕對定位將圖片放置在某個按鈕之上(設定圖片opacity:0.01,讓圖片看不見),然後觸發上下文選單供使用者儲存圖片;

html2canvas使用注意事項:
1、不能夠繪製display:none或者通過position移出顯示區的dom,但是可以繪製z-index:-1的dom,詳見html2canvas踩坑記
2、 圖片模糊解決方案:先根據devicePixelRatio(裝置畫素比)放大canvas,關閉抗鋸齒,然後在放大的canvas上繪製;之後將canvas轉成base64圖片放在原始大小的img上;

// 長按儲存示例程式碼
// 注:生成的圖片需提前設定下opacity:0.01
// html2canvas要注意版本,不同版本api可能不同,此處使用的是0.5.0-beta3版本

var cntElem = $('.share-page')[0];
var shareContent = cntElem; //需要截圖的包裹的(原生的)DOM 物件
var width = shareContent.offsetWidth; //獲取dom 寬度
var height = shareContent.offsetHeight; //獲取dom 高度
var canvas = document.createElement("canvas"); //建立一個canvas節點
var scale = window.devicePixelRatio; //定義任意放大倍數 支援小數
canvas.width = width * scale; //定義canvas 寬度 * 縮放
canvas.height = height * scale; //定義canvas高度 *縮放
canvas.getContext("2d").scale(scale, scale); //獲取context,設定scale
var opts = {
  scale: scale, // 新增的scale 引數
  canvas: canvas, //自定義 canvas
  // logging: true, //日誌開關,便於檢視html2canvas的內部執行流程
  width: width, //dom 原始寬度
  height: height,
  useCORS: true //允許跨域
};

html2canvas(shareContent, opts).then(function (canvas) {
  var context = canvas.getContext('2d');
  // 【重要】關閉抗鋸齒
  context.mozImageSmoothingEnabled = false;
  context.webkitImageSmoothingEnabled = false;
  context.msImageSmoothingEnabled = false;
  context.imageSmoothingEnabled = false;

  var imgURL = canvas.toDataURL("image/png");

  var $img = $('<img src=' + imgURL + '>').css({
    width: canvas.width / scale + 'px',
    height: canvas.height / scale + 'px'
  });

  // 安卓下繫結長按儲存圖片事件
  bindLongTouchSave($img);
  
  // 這裡的.btn.save就是長按儲存按鈕
  $('.btn.save').append($img);
});
複製程式碼
  • visibilityChange事件(頁面可見性發生改變時觸發,一般用於頁面切換到後臺停止播放音樂啥的)

visibilityChange(在早期瀏覽器裡需要加瀏覽器字首),微信也支援此事件(通過window.hidden判斷當前頁面狀態);qq中同樣功能的事件是qbrowserVisibilityChange(通過e.hidden判斷當前頁面狀態)

結語

好啦,這次先總結這麼多,以後等遇到了再繼續總結,相容性問題真的是移動端開發人員的一個大坑哈,O(∩_∩)O哈哈~

相關文章