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
。可能在設計圖對應分辨率的移動設備下,背景會完美貼合顯示,但換到其他分辨率的移動設備下就會出現左右空出1px
到npx
的空隙。
此時將background-size
聲明為100% 100%
,跟隨width
和height
的變化而變化。反正width
和height
都是量好的實際尺寸。
.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
,其實它就是移動端版本的jquery
。zepto
封裝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
可兼容地獲取scrollTop
和scrollHeight
等屬性,在移動端瀏覽器
里屢試不爽。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>
渲染二維碼了。若使用SVG
和Canvas
的方式生成二維碼,那就想方設法把二維碼數據轉換成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 });