做者:JowayYoung
倉庫:Github、CodePen
博客:官網、掘金、思否、知乎
公衆號:IQ前端
特別聲明:原創不易,未經受權不得轉載或抄襲,如需轉載可聯繫筆者受權css
不知不覺在網易已有三年半,佔了一半時間都在與移動端打交道,整個階段都是遇坑填坑的學習過程。移動端開發在前端裏像神同樣地存在,不是說它多難而是說它坑位實在太多了,怎樣填都填不完。Android
和iOS
各顯神通,Android
的系統版本和屏幕分辨率多得難以一招兼容,iOS
的頑固標準和未知特性多得難以快速掌握。html
三年半沉澱經過本文記錄下所遇到的坑位,或許有些坑位還未遇到,但本文記錄的40條坑位絕對能讓同窗們少走不少彎路,特別是前端小白。爲了減小廢話提升本文質量,對如下內容作一些約定。前端
Android
和基於Android
開發的系統iOS
和iPadOS
移動端瀏覽器
,所以大部分坑位的解決方案在桌面端瀏覽器
裏不必定有效Webkit
及其衍生內核在移動端瀏覽器
市場佔有率裏達到驚人的97%
,所以無需太過擔憂CSS3
、ES6
和瀏覽器新特性
的兼容性webpack
構建,所以代碼演示都不會帶上CSS前綴,除非該屬性是Webkit
獨有才會帶上-webkit-
每次填坑都是一次實踐過程,所有坑位的源碼都按語言方向記錄在筆者Github上,如有未記錄的坑位可提PR讓筆者合併,給個Star支持下咧!node
原本想爲每一個坑位都截圖
或錄製GIF
做爲演示,但考慮到目前掘金的Markdown編輯器
操做圖片還存在缺陷就放棄了,每次上傳圖片都會花費不少時間甚至上傳失敗(望掘金的產品小姐姐和程序小哥哥優化喔)。若需演示只能自行復制代碼了。jquery
使用<a>
能快速調用移動設備的電話/短信/郵件
三大通信功能,使用<input>
能快速調用移動設備的的圖庫/文件
。webpack
這些功能方便了頁面與系統的交互,關鍵在於調用格式必定要準確,不然會被移動端瀏覽器
忽略。git
<!-- 撥打電話 -->
<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>
。雖然很方便卻有可能違背需求。github
<!-- 忽略自動識別電話 -->
<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 type="number" pattern="\d*">
彈起數字鍵盤,適合輸入驗證碼等純數字格式。web
<!-- 純數字帶#和* -->
<input type="tel">
<!-- 純數字 -->
<input type="number" pattern="\d*">
複製代碼
經過location.href
與原生應用創建通信渠道,這種頁面與客戶端的通信方式稱爲URL Scheme,其基本格式爲scheme://[path][?query]
,筆者曾經發表過《H5與App的通信方式》講述URL Scheme
的使用。canvas
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全屏,在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瀏覽器
。從網易MTL的測試數據得知,新版的QQ瀏覽器
和UC瀏覽器
已不支持如下<meta>
聲明瞭。
<!-- 強制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
在點擊後會一直處於點擊狀態,需點擊其餘位置才能解除點擊狀態。給<body>
註冊一個空的touchstart事件
可將兩種狀態反轉。
<body ontouchstart></body>
複製代碼
針對移動端,筆者一般會結合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: landscape) {
/* 自定義樣式 */
}
複製代碼
在蘋果系統上非<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 {
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;
}
}
複製代碼
移動端瀏覽器
裏點擊操做會存在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, scrollTop);
});
複製代碼
在蘋果系統上的輸入框輸入文本,keyup/keydown/keypress事件
可能會無效。當輸入框監聽keyup事件
時,逐個輸入英文和數字會有效,但逐個輸入中文不會有效,需按回車鍵纔會有效。
此時可用input事件
代替輸入框的keyup/keydown/keypress事件
。
曾幾什麼時候編寫一個返回頂部
函數麻煩得要死,需scrollTop
、定時器
和條件判斷
三者配合才能完成。其實DOM對象裏隱藏了一個很好用的函數可完成上述功能,一行核心代碼就能搞定。
該函數就是scrollIntoView,它會滾動目標元素的父容器使之對用戶可見,簡單歸納就是相對視窗讓容器滾動到目標元素位置。它有三個可選參數能讓scrollIntoView
滾動起來更優雅。
auto無
,可選smooth平滑
nearest就近對齊
,可選start頂部對齊
、center中間對齊
和end底部對齊
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 (tgt.isIntersecting) {
console.log("已到底部,請求接口");
// 執行接口請求代碼
}
})
observer.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 });
複製代碼
如有未記錄的坑位可提PR讓筆者合併,咱們一塊兒記錄更多的移動端坑位,讓更多前端開發者少走彎路。本文也是筆者2021年在掘金社區的首篇文章,但願今年能產出更多高質量文章。從筆者角度上看,一篇文章不是技術多牛逼筆風多優雅才概括爲好文章,而是總體內容能幫助本身和更多人進步纔算是好文章。向這個方向進發,爲本身打Call。
上述坑位按照HTML方向、CSS方向和JS方向三大類型劃分,能更高效地區分出每一個坑位的使用場景和解決方案,減小混亂記憶。當中說起了CSS方向的不少坑位,這些坑位也屬於一些CSS開發技巧,若喜歡CSS的同窗可瞭解筆者上架的掘金社區首本CSS小冊《玩轉CSS的藝術之美》作更深一步學習。
回看筆者往期高贊文章,也許能收穫更多喔!
4100+
點贊量,15w+
閱讀量4200+
點贊量,13w+
閱讀量1600+
點贊量,5w+
閱讀量700+
點贊量,2.2w+
閱讀量600+
點贊量,1.6w+
閱讀量500+
點贊量,1.5w+
閱讀量最近筆者參加了2020創做者榜單,喜歡筆者可爲筆者打Call喔!你一票我一票,居居上榜靠你們❤️!
❤️關注+點贊+收藏+評論+轉發❤️,原創不易,鼓勵筆者創做更多高質量文章
關注公衆號IQ前端
,一個專一於CSS/JS開發技巧的前端公衆號,更多前端小乾貨等着你喔
資料
免費領取學習資料進羣
拉你進技術交流羣IQ前端
,更多CSS/JS開發技巧只在公衆號推送