40條移動端H5坑位指南

HTML方向

調用系統功能

使用<a>能快速調用移動設備的電話/短信/郵件三大通訊功能,使用<input>能快速調用移動設備的的圖庫/文件

這些功能方便了頁面與系統的交互,關鍵在于調用格式一定要準確,否則會被移動端瀏覽器忽略。

<!-- 撥打電話 -->
<a href="tel:10086">撥打電話給10086小姐姐</a>

<!-- 發送短信 -->
<a href="sms:10086">發送短信給10086小姐姐</a>

<!-- 發送郵件 -->
<a href="mailto:young.joway@aliyun.com">發送郵件給JowayYoung</a>

<!-- 選擇照片或拍攝照片 -->
<input type="file" accept="image/*">

<!-- 選擇視頻或拍攝視頻 -->
<input type="file" accept="video/*">

<!-- 多選文件 -->
<input type="file" multiple>
復制代碼
忽略自動識別

有些移動端瀏覽器會自動將數字字母符號識別為電話/郵箱并將其渲染成上述調用系統功能里的<a>。雖然很方便卻有可能違背需求。

<!-- 忽略自動識別電話 -->
<meta name="format-detection" content="telephone=no">

<!-- 忽略自動識別郵箱 -->
<meta name="format-detection" content="email=no">

<!-- 忽略自動識別電話和郵箱 -->
<meta name="format-detection" content="telephone=no, email=no">
復制代碼
彈出數字鍵盤

使用<input type="tel">彈起數字鍵盤會帶上#*,適合輸入電話。推薦使用<input pattern="\d*">彈起數字鍵盤,適合輸入驗證碼等純數字格式。

<!-- 純數字帶#和* -->
<input type="tel">

<!-- 純數字 -->
<input pattern="\d*">
復制代碼
喚醒原生應用

通過location.href與原生應用建立通訊渠道,這種頁面與客戶端的通訊方式稱為URL Scheme,其基本格式為scheme://[path][?query],筆者曾經發表過《H5與App的通訊方式》講述URL Scheme的使用。

  • scheme:應用標識,表示應用在系統里的唯一標識
  • path:應用行為,表示應用某個頁面或功能
  • query:應用參數,表示應用頁面或應用功能所需的條件參數

URL Scheme一般由前端與客戶端共同協商。喚醒原生應用的前提是必須在移動設備里安裝了該應用,有些移動端瀏覽器即使安裝了該應用也無法喚醒原生應用,因為它認為URL Scheme是一種潛在的危險行為而禁用它,像Safari微信瀏覽器。還好微信瀏覽器可開啟白名單讓URL Scheme有效。

若在頁面引用第三方原生應用的URL Schema,可通過抓包第三方原生應用獲取其URL

<!-- 打開微信 -->
<a href="weixin://">打開微信</a>

<!-- 打開支付寶 -->
<a href="alipays://">打開支付寶</a>

<!-- 打開支付寶的掃一掃 -->
<a href="alipays://platformapi/startapp?saId=10000007">打開支付寶的掃一掃</a>

<!-- 打開支付寶的螞蟻森林 -->
<a href="alipays://platformapi/startapp?appId=60000002">打開支付寶的螞蟻森林</a>
復制代碼
禁止頁面縮放

在智能手機的普及下,很多網站都具備桌面端移動端兩種瀏覽版本,因此無需雙擊縮放查看頁面。禁止頁面縮放可保障移動端瀏覽器能無遺漏地展現頁面所有布局。

<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1, minimum-scale=1, maximum-scale=1">
復制代碼
禁止頁面緩存

Cache-Control指定請求和響應遵循的緩存機制,不想使用瀏覽器緩存就禁止唄!

<meta http-equiv="Cache-Control" content="no-cache">
復制代碼
禁止字母大寫

有時在輸入框里輸入文本會默認開啟首字母大寫糾正,就是輸入首字母小寫會被自動糾正成大寫,特么的煩。直接聲明autocapitalize=off關閉首字母大寫功能和autocorrect=off關閉糾正功能。

<input autocapitalize="off" autocorrect="off">
復制代碼
針對Safari配置

貼一些Safari較零散且少用的配置。

<!-- 設置Safari全屏,在iOS7+無效 -->
<meta name="apple-mobile-web-app-capable" content="yes">

<!-- 改變Safari狀態欄樣式,可選default/black/black-translucent,需在上述全屏模式下才有效 -->
<meta name="apple-mobile-web-app-status-bar-style" content="black">

<!-- 添加頁面啟動占位圖 -->
<link rel="apple-touch-startup-image" href="pig.jpg" media="(device-width: 375px)">

<!-- 保存網站到桌面時添加圖標 -->
<link rel="apple-touch-icon" sizes="76x76" href="pig.jpg">

<!-- 保存網站到桌面時添加圖標且清除默認光澤 -->
<link rel="apple-touch-icon-precomposed" href="pig.jpg">
復制代碼
針對其他瀏覽器配置

貼一些其他瀏覽器較零散且少用的配置,主要是常用的QQ瀏覽器UC瀏覽器360瀏覽器

<!-- 強制QQ瀏覽器豎屏 -->
<meta name="x5-orientation" content="portrait">

<!-- 強制QQ瀏覽器全屏 -->
<meta name="x5-fullscreen" content="true">

<!-- 開啟QQ瀏覽器應用模式 -->
<meta name="x5-page-mode" content="app">

<!-- 強制UC瀏覽器豎屏 -->
<meta name="screen-orientation" content="portrait">

<!-- 強制UC瀏覽器全屏 -->
<meta name="full-screen" content="yes">

<!-- 開啟UC瀏覽器應用模式 -->
<meta name="browsermode" content="application">

<!-- 開啟360瀏覽器極速模式 -->
<meta name="renderer" content="webkit">
復制代碼
讓:active有效,讓:hover無效

有些元素的:active可能會無效,而元素的:hover在點擊后會一直處于點擊狀態,需點擊其他位置才能解除點擊狀態。給<body>注冊一個空的touchstart事件可將兩種狀態反轉。

<body ontouchstart></body>
復制代碼

CSS方向

自動適應布局

針對移動端,筆者通常會結合JS依據屏幕寬度設計圖寬度的比例動態聲明<html>font-size,以rem為長度單位聲明所有節點的幾何屬性,這樣就能做到大部分移動設備的頁面兼容,兼容出入較大的地方再通過媒體查詢做特別處理。

筆者通常將rem布局比例設置成1rem=100px,即在設計圖上100px長度在CSS代碼上使用1rem表示。

function AutoResponse(width = 750) {
    const target = document.documentElement;
    if (target.clientWidth >= 600) {
        target.style.fontSize = "80px";
    } else {
        target.style.fontSize = target.clientWidth / width * 100 + "px";
    }
}
AutoResponse();
window.addEventListener("resize", () => AutoResponse());
復制代碼

當然還可依據屏幕寬度設計圖寬度的比例使用calc()動態聲明<html>font-size,這樣就能節省上述代碼。不對,是完全代替上述代碼。

html {
    font-size: calc(100vw / 7.5);
}
復制代碼

若以iPad Pro分辨率1024px為移動端和桌面端的斷點,還可結合媒體查詢做斷點處理。1024px以下使用rem布局,否則不使用rem布局

@media screen and (max-width: 1024px) {
    html {
        font-size: calc(100vw / 7.5);
    }
}
復制代碼
自動適應背景

使用rem布局聲明一個元素背景,多數情況會將background-size聲明為cover。可能在設計圖對應分辨率的移動設備下,背景會完美貼合顯示,但換到其他分辨率的移動設備下就會出現左右空出1pxnpx的空隙。

此時將background-size聲明為100% 100%,跟隨widthheight的變化而變化。反正widthheight都是量好的實際尺寸。

.elem {
    width: 1rem;
    height: 1rem;
    background: url("pig.jpg") no-repeat center/100% 100%;
}
復制代碼
監聽屏幕旋轉

你還在使用JS判斷橫屏豎屏調整樣式嗎?那就真的Out了。

/* 豎屏 */
@media all and (orientation: portrait) {
    /* 自定義樣式 */
}
/* 橫屏 */
@media all and (orientation: portrait) {
    /* 自定義樣式 */
}
復制代碼
支持彈性滾動

在蘋果系統上非<body>元素的滾動操作可能會存在卡頓,但安卓系統不會出現該情況。通過聲明overflow-scrolling:touch調用系統原生滾動事件優化彈性滾動,增加頁面滾動的流暢度。

body {
    -webkit-overflow-scrolling: touch;
}
.elem {
    overflow: auto;
}
復制代碼
禁止滾動傳播

桌面端瀏覽器不一樣,移動端瀏覽器有一個奇怪行為。當頁面包含多個滾動區域時,滾完一個區域后若還存在滾動動量則會將這些剩余動量傳播到下一個滾動區域,造成該區域也滾動起來。這種行為稱為滾動傳播

若不想產生這種奇怪行為可直接禁止。

.elem {
    overscroll-behavior: contain;
}
復制代碼
禁止屏幕抖動

對于一些突然出現滾動條的頁面,可能會產生左右抖動的不良影響。在一個滾動容器里,打開彈窗就隱藏滾動條,關閉彈窗就顯示滾動條,來回操作會讓屏幕抖動起來。提前聲明滾動容器的padding-right為滾動條寬度,就能有效消除這個不良影響。

每個移動端瀏覽器的滾動條寬度都有可能不一致,甚至不一定占位置,通過以下方式能間接計算出滾動條的寬度。100vw為視窗寬度,100%為滾動容器內容寬度,相減就是滾動條寬度,妥妥的動態計算。

body {
    padding-right: calc(100vw - 100%);
}
復制代碼
禁止長按操作

有時不想用戶長按元素呼出菜單進行點鏈接打電話發郵件保存圖片掃描二維碼等操作,聲明touch-callout:none禁止用戶長按操作。

有時不想用戶復制粘貼盜文案,聲明user-select:none禁止用戶長按操作和選擇復制。

* {
    /* pointer-events: none; */ /* 微信瀏覽器還需附加該屬性才有效 */
    user-select: none; /* 禁止長按選擇文字 */
    -webkit-touch-callout: none;
}
復制代碼

但聲明user-select:none會讓<input><textarea>無法輸入文本,可對其聲明user-select:auto排除在外。

input,
textarea {
    user-select: auto;
}
復制代碼
禁止字體調整

旋轉屏幕可能會改變字體大小,聲明text-size-adjust:100%讓字體大小保持不變。

* {
    text-size-adjust: 100%;
}
復制代碼
禁止高亮顯示

觸摸元素會出現半透明灰色遮罩,不想要!

* {
    -webkit-tap-highlight-color: transparent;
}
復制代碼
禁止動畫閃屏

在移動設備上添加動畫,多數情況會出現閃屏,給動畫元素的父元素構造一個3D環境就能讓動畫穩定運行了。

.elem {
    perspective: 1000;
    backface-visibility: hidden;
    transform-style: preserve-3d;
}
復制代碼
美化表單外觀

表單元素樣式太丑希望自定義,appearance:none來幫你。

button,
input,
select,
textarea {
    appearance: none;
    /* 自定義樣式 */
}
復制代碼
美化滾動占位

滾動條樣式太丑希望自定義,::-webkit-scrollbar-*來幫你。記住以下三個關鍵詞就能隨機應變了。

  • ::-webkit-scrollbar:滾動條整體部分
  • ::-webkit-scrollbar-track:滾動條軌道部分
  • ::-webkit-scrollbar-thumb:滾動條滑塊部分
::-webkit-scrollbar {
    width: 6px;
    height: 6px;
    background-color: transparent;
}
::-webkit-scrollbar-track {
    background-color: transparent;
}
::-webkit-scrollbar-thumb {
    border-radius: 3px;
    background-image: linear-gradient(135deg, #09f, #3c9);
}
復制代碼
美化輸入占位

輸入框占位文本太丑,::-webkit-input-placeholder來幫你。

input::-webkit-input-placeholder {
    color: #66f;
}
復制代碼
對齊輸入占位

有強迫癥的同學總會覺得輸入框文本位置整體偏上,感覺未居中心里就癢癢的。桌面端瀏覽器里聲明line-height等于height就能解決,但移動端瀏覽器里還是未能解決,需將line-height聲明為normal才行。

input {
    line-height: normal;
}
復制代碼
對齊下拉選項

下拉框選項默認向左對齊,是時候改改向右對齊了。

select option {
    direction: rtl;
}
復制代碼
修復點擊無效

在蘋果系統上有些情況下非可點擊元素監聽click事件可能會無效,針對該情況只需對不觸發click事件的元素聲明cursor:pointer就能解決。

.elem {
    cursor: pointer;
}
復制代碼
識別文本換行

多數情況會使用JS換行文本,那就真的Out了。若接口返回字段包含\n<br>,千萬別替換掉,可聲明white-space:pre-line交由瀏覽器做斷行處理。

* {
    white-space: pre-line;
}
復制代碼
開啟硬件加速

想動畫更流暢嗎,開啟GPU硬件加速唄!

.elem {
    transform: translate3d(0, 0, 0);
    /* transform: translateZ(0); */
}
復制代碼
描繪像素邊框

萬年話題,如何描繪一像素邊框

.elem {
    position: relative;
    width: 200px;
    height: 80px;
    &::after {
        position: absolute;
        left: 0;
        top: 0;
        border: 1px solid #f66;
        width: 200%;
        height: 200%;
        content: "";
        transform: scale(.5);
        transform-origin: left top;
    }
}
復制代碼
控制溢出文本

萬年話題,如何控制文本做單行溢出多行溢出

.elem {
    width: 400px;
    line-height: 30px;
    font-size: 20px;
    &.sl-ellipsis {
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
    }
    &.ml-ellipsis {
        display: -webkit-box;
        overflow: hidden;
        text-overflow: ellipsis;
        -webkit-line-clamp: 3;
        -webkit-box-orient: vertical;
    }
}
復制代碼

JS方向

禁止點擊穿透

移動端瀏覽器里點擊操作會存在300ms延遲,往往會造成點擊延遲甚至點擊無效,這個是眾所周知的事情。

2007年蘋果發布首款iPhone搭載的Safari為了將桌面端網站能較好地展示在移動端瀏覽器上而使用了雙擊縮放。該方案就是上述300ms延遲的主要原因,當用戶執行第一次單擊后會預留300ms檢測用戶是否繼續執行單擊,若是則執行縮放操作,若否則執行點擊操作。鑒于該方案的成功,其他移動端瀏覽器也復制了該方案,現在幾乎所有移動端瀏覽器都配備該功能。而該方案引發的點擊延遲被稱為點擊穿透

在前端領域里最早解決點擊穿透是jQuery時代zepto,估計現在大部分同學都未使用過zepto,其實它就是移動端版本的jqueryzepto封裝tap事件能有效地解決點擊穿透,通過監聽document上的touch事件完成tap事件的模擬,并將tap事件冒泡到document上觸發。

移動端瀏覽器上不使用click事件而使用touch事件是因為click事件有著明顯的延遲,后續又出現fastclick。該解決方案監聽用戶是否做了雙擊操作,所以還是可直接使用click事件,而點擊穿透就交給該fastclick自動判斷。更多fastclick原理可自行百度,在此不作過多介紹。

fastclick有現成的NPM包,可直接安裝到項目里。引入fastclick可使用click事件代替tap事件,接入方式極其簡單。

import Fastclick from "fastclick";

FastClick.attach(document.body);
復制代碼
禁止滑動穿透

移動端瀏覽器里出現彈窗時,若在屏幕上滑動能觸發彈窗底下的內容跟著滾動,這個是眾所周知的事情。

首先明確解決滑動穿透需保持哪些交互行為,那就是除了彈窗內容能點擊或滾動,其他內容都不能點擊或滾動。目前很多解決方案都無法做到這一點,全部解決方案都能禁止<body>的滾動行為卻引發其他問題。

  • 彈窗打開后內部內容無法滾動
  • 彈窗關閉后頁面滾動位置丟失
  • Webview能上下滑動露出底色

當打開彈窗時給<body>聲明position:fixed;left:0;width:100%并動態聲明top。聲明position:fixed會導致<body>滾動條消失,此時會發現雖然無滑動穿透,但頁面滾動位置早已丟失。通過scrollingElement獲取頁面當前滾動條偏移量并將其取負值且賦值給top,那么在視覺上就無任何變化。當關閉彈窗時移除position:fixed;left:0;width:100%和動態top

scrollingElement可兼容地獲取scrollTopscrollHeight等屬性,在移動端瀏覽器里屢試不爽。document.scrollingElement.scrollHeight可完美代替曾經的document.documentElement.scrollHeight || document.body.scrollHeight,一眼看上去就是代碼減少了。

該解決方案在視覺上無任何變化,完爆其他解決方案,其實就是一種反向思維和障眼法。該解決方案完美解決固定彈窗滾動彈窗<body>全局滾動的影響,當然也可用于局部滾動容器里,因此很值得推廣。

body.static {
    position: fixed;
    left: 0;
    width: 100%;
}
復制代碼
const body = document.body;
const openBtn = document.getElementById("open-btn");
const closeBtn = document.getElementById("close-btn");
openBtn.addEventListener("click", e => {
    e.stopPropagation();
    const scrollTop = document.scrollingElement.scrollTop;
    body.classList.add("static");
    body.style.top = `-${scrollTop}px`;
});
closeBtn.addEventListener("click", e => {
    e.stopPropagation();
    body.classList.remove("static");
    body.style.top = "";
});
復制代碼
支持往返刷新

點擊移動端瀏覽器前進按鈕后退按鈕,有時不會自動執行舊頁面的JS代碼,這與往返緩存有關。這種情況在Safari上特別明顯,簡單概括就是往返頁面無法刷新。

往返緩存指瀏覽器為了在頁面間執行前進后退操作時能擁有更流暢體驗的一種策略,以下簡稱BFCache。該策略具體表現為:當用戶前往新頁面前將舊頁面的DOM狀態保存在BFCache里,當用戶返回舊頁面前將舊頁面的DOM狀態從BFCache里取出并加載。大部分移動端瀏覽器都會部署BFCache,可大大節省接口請求的時間和帶寬。

了解什么是BFCache再對癥下藥,解決方案就在window.onunload上做文章。

// 在新頁面監聽頁面銷毀事件
window.addEventListener("onunload", () => {
    // 執行舊頁面代碼
});
復制代碼

若在Vue SPA上使用keep-alive也不能讓頁面刷新,可將接口請求放到beforeRouteEnter()里。

當然還有另一種解決方案。pageshow事件在每次頁面加載時都會觸發,無論是首次加載還是再次加載都會觸發,這就是它與load事件的區別。pageshow事件暴露的persisted可判斷頁面是否從BFCache里取出。

window.addEventListener("pageshow", e => e.persisted && location.reload());
復制代碼

若瀏覽器不使用<meta http-equiv="Cache-Control" content="no-cache">禁用緩存,該解決方案還是很值得一用。

解析有效日期

在蘋果系統上解析YYYY-MM-DD HH:mm:ss這種日期格式會報錯Invalid Date,但在安卓系統上解析這種日期格式完全無問題。

new Date("2019-03-31 21:30:00"); // Invalid Date
復制代碼

查看Safari相關開發手冊發現可用YYYY/MM/DD HH:mm:ss這種日期格式,簡單概括就是年月日必須使用/銜接而不能使用-銜接。當然安卓系統也支持該格式,然而接口返回字段的日期格式通常是YYYY-MM-DD HH:mm:ss,那么需替換其中的-/

const date = "2019-03-31 21:30:00";
new Date(date.replace(/\-/g, "-"));
復制代碼
修復高度坍塌

當頁面同時出現以下三個條件時,鍵盤占位會把頁面高度壓縮一部分。當輸入完成鍵盤占位消失后,頁面高度有可能回不到原來高度,產生坍塌導致Webview底色露臉,簡單概括就是輸入框失焦后頁面未回彈。

  • 頁面高度過小
  • 輸入框在頁面底部或視窗中下方
  • 輸入框聚焦輸入文本

只要保持前后滾動條偏移量一致就不會出現上述問題。在輸入框聚焦時獲取頁面當前滾動條偏移量,在輸入框失焦時賦值頁面之前獲取的滾動條偏移量,這樣就能間接還原頁面滾動條偏移量解決頁面高度坍塌。

const input = document.getElementById("input");
let scrollTop = 0;
input.addEventListener("focus", () => {
    scrollTop = document.scrollingElement.scrollTop;
});
input.addEventListener("blur", () => {
    document.scrollingElement.scrollTo(0, this.scrollTop);
});
復制代碼
修復輸入監聽

在蘋果系統上的輸入框輸入文本,keyup/keydown/keypress事件可能會無效。當輸入框監聽keyup事件時,逐個輸入英文和數字會有效,但逐個輸入中文不會有效,需按回車鍵才會有效。

此時可用input事件代替輸入框的keyup/keydown/keypress事件

簡化回到頂部

曾幾何時編寫一個返回頂部函數麻煩得要死,需scrollTop定時器條件判斷三者配合才能完成。其實DOM對象里隱藏了一個很好用的函數可完成上述功能,一行核心代碼就能搞定。

該函數就是scrollIntoView,它會滾動目標元素的父容器使之對用戶可見,簡單概括就是相對視窗讓容器滾動到目標元素位置。它有三個可選參數能讓scrollIntoView滾動起來更優雅。

  • behavior:動畫過渡效果,默認auto無,可選smooth平滑
  • inline:水平方向對齊方式,默認nearest就近對齊,可選start頂部對齊center中間對齊end底部對齊
  • block:垂直方向對齊方式,默認start頂部對齊,可選center中間對齊end底部對齊nearest就近對齊
const gotopBtn = document.getElementById("gotop-btn");
openBtn.addEventListener("click", () => document.body.scrollIntoView({ behavior: "smooth" }));
復制代碼

當然還可滾動到目標元素位置,只需將document.body修改成目標元素的DOM對象。一行核心代碼就能搞掂的事情為何還編寫那么多代碼去完成,不累嗎?

簡化懶性加載

與上述簡化回到頂部一樣,編寫一個懶性加載函數也同樣需scrollTop定時器條件判斷三者配合才能完成。其實DOM對象里隱藏了一個很好用的函數可完成上述功能,該函數無需監聽容器的scroll事件,通過瀏覽器自身機制完成滾動監聽。

該函數就是IntersectionObserver,它提供一種異步觀察目標元素及其祖先元素或頂級文檔視窗交叉狀態的方法。詳情可參照MDN文檔,在此不作過多介紹。

懶性加載的第一種使用場景:圖片懶加載。只需確認圖片進入可視區域就賦值加載圖片,賦值完成還需對圖片停止監聽。

<img data-src="pig.jpg">
<!-- 很多<img> -->
復制代碼
const imgs = document.querySelectorAll("img.lazyload");
const observer = new IntersectionObserver(nodes => {
    nodes.forEach(v => {
        if (v.isIntersecting) { // 判斷是否進入可視區域
            v.target.src = v.target.dataset.src; // 賦值加載圖片
            observer.unobserve(v.target); // 停止監聽已加載的圖片
        }
    });
});
imgs.forEach(v => observer.observe(v));
復制代碼

懶性加載的第二種使用場景:下拉加載。在列表最底部部署一個占位元素且該元素無任何高度或實體外觀,只需確認占位元素進入可視區域就請求接口加載數據。

<ul>
    <li></li>
    <!-- 很多<li> -->
</ul>
<!-- 也可將#bottom以<li>的形式插入到<ul>內部的最后位置 -->
<div id="bottom"></div>
復制代碼
const bottom = document.getElementById("bottom");
const observer = new IntersectionObserver(nodes => {
    const tgt = nodes[0]; // 反正只有一個
    if (item.isIntersecting) {
        console.log("已到底部,請求接口");
        // 執行接口請求代碼
    }
})
bottom.observe(bottom);
復制代碼
優化掃碼識別

通常移動端瀏覽器都會配備長按二維碼圖片識別鏈接的功能,但長按二維碼可能無法識別或錯誤識別。二維碼表面看上去是一張圖片,可二維碼生成方式卻五花八門,二維碼生成方式有以下三種。

  • 使用<img>渲染
  • 使用<svg>渲染
  • 使用<canvas>渲染

經過網易MTL測試的數據顯示,大部分移動端瀏覽器只能識別<img>渲染的二維碼,為了讓全部移動端瀏覽器都能識別二維碼,那只能使用<img>渲染二維碼了。若使用SVGCanvas的方式生成二維碼,那就想方設法把二維碼數據轉換成Base64再賦值到<img>src上。

一個頁面可能存在多個二維碼,若長按二維碼只能識別最后一個,那只能控制每個頁面只存在一個二維碼。

自動播放媒體

常見媒體元素包括音頻<audio>和視頻<video>,為了讓用戶得到更好的媒體播放體驗與不盲目浪費用戶流量,大部分移動端瀏覽器都明確規定不能自動播放媒體或默認屏蔽autoplay。為了能讓媒體在頁面加載完成后自動播放,只能顯式聲明播放。

const audio = document.getElementById("audio");
const video = document.getElementById("video");
audio.play();
video.play();
復制代碼

對于像微信瀏覽器這樣的內置瀏覽器,還需監聽其應用SDK加載完成才能觸發上述代碼,以保障WebView正常渲染。其他內置瀏覽器同理,在此不作過多介紹。

document.addEventListener("WeixinJSBridgeReady", () => {
    // 執行上述媒體自動播放代碼
});
復制代碼

在蘋果系統上明確規定用戶交互操作開始后才能播放媒體,未得到用戶響應會被Safari自動攔截,因此需監聽用戶首次觸摸操作并觸發媒體自動播放,而該監聽僅此一次。

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

推薦閱讀更多精彩內容