溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

手機(jī)端Web開發(fā)中遇到的問題有哪些

發(fā)布時(shí)間:2021-11-17 09:44:30 來源:億速云 閱讀:135 作者:柒染 欄目:web開發(fā)

本篇文章給大家分享的是有關(guān)手機(jī)端Web開發(fā)中遇到的問題有哪些,小編覺得挺實(shí)用的,因此分享給大家學(xué)習(xí),希望大家閱讀完這篇文章后可以有所收獲,話不多說,跟著小編一起來看看吧。

 retina 圖片兼容

這個(gè) feature 應(yīng)該不僅僅只關(guān)心 手機(jī)端, 而且還包括PC, 因?yàn)樘O果不僅僅在手機(jī)端 (從 iphone4 開始), 而且在, MAC 上也使用了  retina. 首先, retina 的意思就是, dpr(device-pixel-ratio)是普通屏幕的兩倍. 對(duì)比于 CSS 來說就是, 原來在 css  中設(shè)置的是 1px , 在實(shí)際的屏幕顯示時(shí), 也是 1px. 但是, 在 retina 下, css 的 1px 就是實(shí)際屏幕的 2px.

手機(jī)端Web開發(fā)中遇到的問題有哪些

這樣的結(jié)果就是:

手機(jī)端Web開發(fā)中遇到的問題有哪些

有同學(xué)會(huì)想, 會(huì)啥會(huì)這樣呢? 命名看起來大小一樣的, 為什么圖片變模糊了?這實(shí)際上是位圖的特性. 比如一個(gè) jpg 文件, 大小是 200×300.  那么他的實(shí)際屏幕像素就是 200px × 300px. 放在 dpr=1 的屏幕中, 大小設(shè)置為:

width: 200px;  height:300px;

這樣, 當(dāng)然可以正常顯示. 但在 retina 中, 每個(gè) css px 等于 2 倍的 px. 這樣, 原來正常顯示的圖片就被放大了一倍.  原來圖片上每個(gè)點(diǎn),可以正好的放在 dpr=1 的屏幕中, 而在 dpr=2 時(shí), 每個(gè)點(diǎn)都被拆分了, 所以就有鋸齒造成模糊的現(xiàn)象.

而解決辦法也有很多.

使用 media query

這種方法適用于背景圖的添加. 使用到的是 css3 提供的 device-pixel-ratio query 來進(jìn)行執(zhí)行. 簡單的demo就是:

#myimage {     width: 400px;     height: 300px;     background: url(lo-res.jpg) 0 0 no-repeat; }  // 這里主要針對(duì)的是 Android 的一些設(shè)備 @media screen and (-webkit-min-device-pixel-ratio: 1.5), screen and (min--moz-device-pixel-ratio: 1.5), screen and (-o-min-device-pixel-ratio: 3/2), screen and (min-device-pixel-ratio: 1.5) {     #myimage {         background-image: url(hi-res.jpg);     } }  // 如果你想針對(duì)蘋果的, 則可以直接使用: @media only screen and (-webkit-device-pixel-ratio: 2),        only screen and (-moz-device-pixel-ratio: 2),        only screen and (-o-device-pixel-ratio: 2/1),        only screen and (device-pixel-ratio: 2) {         #myimage {         background-image: url(hi-res.jpg);     } }

但這樣成本很大, 而且每次都需要準(zhǔn)備兩份, 做一些價(jià)值特別低的工作.

使用 js 判斷

除了上面寫冗余的 css 代碼外, 還可以使用 js 進(jìn)行判斷. 然后,替換 data-src 里面的內(nèi)容進(jìn)行懶加載.

if (window.devicePixelRatio > 1) {         var images = $("img");         images.each(function(i) {             var x1 = $(this).attr('data-src');             $(this).attr('src',x1);         });     }

而且,該屬性的支持度挺高的, 基本上所有的手機(jī)端和PC 都支持, 除了 IE8.

使用矢量圖

在 web 中使用矢量圖的方式有很多. 比如, SVG, Fonts. 這兩個(gè), 應(yīng)該是最適合的, 不過, 在畫圖時(shí), 大多都是位圖的形式, 所以,  需要轉(zhuǎn)換為 SVG 和 fonts 來說, 難度有點(diǎn)大. 針對(duì)一些小的 logo 和 icon 來說, 還是沒太大的問題的. 并且,  上述的兩種方式所占用的空間大小也是很小的.

手機(jī)基本情況

現(xiàn)在手機(jī)的問題不在 js 腳本, 而在頁面渲染. 因?yàn)? 手機(jī)的屏幕顯示全是通過 CPU 進(jìn)行處理. 而沒有像 PC  端一樣有獨(dú)立的顯卡專門來對(duì)圖像進(jìn)行繪制.

手機(jī)上的鍵盤

一般遇到需要輸入的元素標(biāo)簽, 比如, input 當(dāng)獲取焦點(diǎn)時(shí), 都會(huì)觸發(fā)鍵盤的彈出. 但, 對(duì)于 ios 和安卓,  這兩者的鍵盤彈出的處理方式不一樣.

ios 的鍵盤

鍵盤的渲染有兩種方式:

  • 如果 input 已經(jīng)在鍵盤的上方, 則只是會(huì)將控件向上推一點(diǎn), 推導(dǎo)鍵盤的上方.

  • 如果 input 在鍵盤的下方,鍵盤會(huì)覆蓋該控件, 并將整個(gè)頁面向上推, 直到控件推到鍵盤上方為止.

另外, 當(dāng)在 ios7 一下時(shí), 如果有元素是 fixed 屬性. 那么,此時(shí)打開 鍵盤時(shí), fixed 有可能會(huì)當(dāng)做 absolute 進(jìn)行渲染.  所以, 這真是個(gè)問題.

android 的鍵盤

同樣,也有兩種情況.

  • ***種沒問題

  • 第二種, 當(dāng) input 在鍵盤的下方, 會(huì)將整個(gè) document 的高度增加, 直到控件高度超過鍵盤高度為止.

對(duì)于 android 將整個(gè) document 向上推的情況, 對(duì)于絕對(duì)定位和 fixed 屬性定位來說. 會(huì)存在一定的問題. 增加 document  并未增高 viewport 的位置, 所以, 如果使用 fixed 可能會(huì)出現(xiàn), 元素跑到鍵盤下面. 但, 由于鍵盤是在整個(gè)瀏覽器上方的, 所以,  你也不可能覆蓋掉鍵盤. 一般的解決辦法就是, 監(jiān)聽輸入的 focus 事件, 來動(dòng)態(tài) 設(shè)置fixed 的位置.(不過好復(fù)雜).

軟盤類型

針對(duì)于不同的輸入,鍵盤上顯示的類型實(shí)際上是不一樣的, 一般兼容性比較好的是:數(shù)字/手機(jī)號(hào). 可以設(shè)置為:

input[type=tel]  input[type=number]

軟盤人工彈起

當(dāng)用戶沒有觸發(fā) input 的 focus 事件. 而是開發(fā)者人工觸發(fā)的, 這里就有兩種不同的情況.

IOS

ios6 以前, 當(dāng)控件觸發(fā)了 focus 事件, 但, focus 不是用戶觸發(fā)的, 那么鍵盤是不會(huì)彈起的.

在 ios6 以后, 可以手動(dòng)添加一個(gè) autofocus 屬性即可.

Android

只要不是用戶觸發(fā)的,都不能彈起.

鍵盤的收起

鍵盤的收起直接觸發(fā) js 的 blur 事件即可.

頁面滾動(dòng)

設(shè)計(jì)到頁面滾動(dòng)有兩個(gè)事件, 一個(gè)是 scroll, 一個(gè)是 touchmove.

手機(jī)端為了解決性能問題, 當(dāng)頁面進(jìn)行滾動(dòng)時(shí), js 進(jìn)行的動(dòng)態(tài)渲染是無效的, 即, 使用 js 改變頁面上元素的位置,是無效的. 知道頁面滾動(dòng)結(jié)束才行.  這種效果主要體現(xiàn)在 scroll 事件觸發(fā)的機(jī)制上. 在 ios8 以下, 當(dāng)頁面滾動(dòng)時(shí), js 的渲染被暫停了. 而,對(duì)于 Andriod 4.0 以上來說,  scroll 觸發(fā)都是連續(xù)滾動(dòng)的.

如果你想設(shè)置局部滾動(dòng), 可以添加 -webkit-overflow-scrolling: touch css 屬性.

flex 問題

由于歷史原因, 想在 web 上實(shí)現(xiàn) flex 的效果. 則需要注意他的兼容性, 因?yàn)?flex 有三個(gè)版本,  而且三個(gè)版本的支持性都不一樣.分別是:

  • display: box

  • display: flexbox

  • display: flex

由于 Android 使用的是 Webkit 開源內(nèi)核, 我們需要給 flex 加上 webkit 前綴, 來兼容 低版本 Android.

display: -webkit-box; display: -moz-box; display: -ms-flexbox; display: -webkit-flex; display: flex;

目前的兼容性是:

手機(jī)端Web開發(fā)中遇到的問題有哪些

  • old 使用的是 display: box;

  • tweener 使用的是 display: flexbox;

  • new 使用的是 display: flex;

fixed 問題

在 mobile 里面使用 fixed 是一個(gè)比較復(fù)雜的問題. 因?yàn)?在輸入時(shí), 往往還會(huì)設(shè)計(jì)到鍵盤的彈出, 鑒于 ios 和 android  的不同效果. fixed 有可能在鍵盤彈出時(shí), 出現(xiàn)錯(cuò)位的現(xiàn)象. 例如:

手機(jī)端Web開發(fā)中遇到的問題有哪些

具體參考: fixed. 在 ios5 以前是不支持 fixed, android 在 4.x 之后, fixed 基本上才可用.

touch 事件解析

300ms click 時(shí)延

click 時(shí)延算是, web 手機(jī)開發(fā)的一個(gè)坑吧. 因?yàn)閺S商在設(shè)計(jì)手機(jī)端時(shí), 主要, 考慮到縮放的事.

即:

當(dāng)***次點(diǎn)擊時(shí), 并不會(huì)觸發(fā) click 時(shí)間, 瀏覽器會(huì)等待 300ms 時(shí)延, 并判斷你在 300ms 內(nèi),有沒有再次點(diǎn)擊, 如果有, 則會(huì)觸發(fā)  zoom in 的效果。 后來, 300ms 時(shí)延被取消了, 同時(shí), 長按選中文本也取消了. 后來覺得不行, 又加上了. 在 Chrome 32+, IE/FF  都是 Ok的. 最近在 IOS 9.3 中也得到了修復(fù).

不過前期是, 你需要在 head 標(biāo)簽里面加上.

// 告訴瀏覽器取消雙擊放大的效果  <meta name="viewport" content="width=device-width">

或者給特定的 tag 加上特定的 css 屬性

html {      touch-action: manipulation;  }

不過 FF 不支持.

click 點(diǎn)透

這個(gè) feature 應(yīng)該算是比較經(jīng)典了. 當(dāng)一個(gè)罩層覆蓋在一個(gè) a 標(biāo)簽上。

<div id="model"></div>  <a href="www.villainhr.com">www.villainhr.com</a>

此時(shí), model 是覆蓋在 a 標(biāo)簽上的. 當(dāng)點(diǎn)擊罩層, 罩層消失. (罩層綁定的是 tap 事件) 由于, click 事件有 300ms 時(shí)延,  所以, 此時(shí) a 標(biāo)簽的跳轉(zhuǎn)效果會(huì)觸發(fā). 解決辦法是:

  • 設(shè)置罩層延時(shí)消失效果. 延時(shí)時(shí)間設(shè)置為 300ms+ 即可.

  • 在 touchend 里面執(zhí)行 preventDefault()

  • 使用插件禁止掉 click 事件, 轉(zhuǎn)而使用模擬的.

觸摸事件詳解

在手機(jī)上是沒有關(guān)于鼠標(biāo)的相關(guān)操作的, 比如 hover, mouseover, mousenter等等. 只有, 相關(guān)的 touch 事件.

  • touchstart 當(dāng)***根手指觸摸到屏幕時(shí), 觸發(fā).

  • touchmove 當(dāng)某一個(gè)手指在屏幕上移動(dòng)時(shí), 觸發(fā).

  • touchend 當(dāng)手指從屏幕上移開時(shí), 觸發(fā).

  • touchcancel 當(dāng)手指觸控被打斷時(shí)觸發(fā). 具體有一下幾種.

。其他事件的發(fā)生打斷了 touch 事件. 比如, js 操作強(qiáng)制跳轉(zhuǎn)

。當(dāng)瀏覽器的 UI 覆蓋到當(dāng)前的 web 上

。觸摸的手指數(shù)超過了瀏覽器的支持?jǐn)?shù)量. 如果發(fā)生, 那么***根觸摸的手指會(huì)被取消

// 暫不支持下列兩個(gè)事件

  • touchenter 當(dāng)手指進(jìn)入指定元素

  • touchleave 當(dāng)手指移出指定元素

因?yàn)樵谟|發(fā) touch 事件時(shí), 不僅僅只是相關(guān)的 touch 事件會(huì)觸發(fā), 還會(huì)觸發(fā)相關(guān)的 mouse 和 click 事件. 所以, 如果 mouse  和 click 事件有影響時(shí), 則需要顯示的使用 event.preventDefault() 取消掉后面的觸發(fā)機(jī)制.

在每個(gè) touch 事件里面, 還會(huì)返回掛載到 event 上的屬性, 常用的有:

  • touches: 當(dāng)前屏幕上的屬性

  • targetTouches: 在指定 DOM 元素上的屬性

  • changedTouches: 返回觸發(fā)時(shí)間的相關(guān)手指數(shù). 比如, touchmove 事件中, 返回正在移動(dòng)的手指. 在 touchend 事件中,  返回移除的手指.

并且每一個(gè) touch 上面都會(huì)附帶相關(guān)的屬性.

  • identifier: 每一個(gè)手指***的 ID

  • target: 返回一開始觸發(fā) touch 事件的 DOM 元素

  • screenX/Y: 返回相對(duì)于整個(gè)手機(jī)屏幕而言的位置.

  • pageX/Y: 返回相對(duì)于整個(gè)頁面的位置, 包括 scroll 的距離.

  • clientX/Y: 返回相對(duì)于瀏覽器 viewport 的位置. 不包含 scroll 的距離.

  • radiusX/Y: 返回手勢橢圓的長軸和短軸的大小. 目前來說, 還不支持. 和 screenX/Y 有點(diǎn)類似.

touchmove 的坑

移動(dòng)而不滾動(dòng)

當(dāng)觸發(fā) touchmove 時(shí). 如果,不加限制的話, 往往會(huì)觸發(fā) scroll 的效果. 為了消除這樣的問題, 只需要將默認(rèn)行為禁掉就 ok.

document.body.addEventListener('touchmove', function(event) {   event.preventDefault(); }, false);

不要將 touchmove 來用作渲染觸發(fā)

因?yàn)? touchmove 的機(jī)制是瀏覽器自身來決定的. 他觸發(fā)的次數(shù)是很有限的. 所以, 我們一般只是利用 touchmove 來獲得數(shù)據(jù),  而渲染則需要使用 requestAnimationFrame .

var touches = [] canvas.addEventListener('touchmove', function(event) {   touches = event.touches; }, false);  // Setup a 60fps timer timer = setInterval(function() {   renderTouches(touches); }, 15);

媒體查詢

媒體查詢機(jī)制在 css2 里面就已經(jīng)提出來. 比如, 針對(duì)打印機(jī)的:

<link rel="stylesheet" media="print" href="printer.css">

不過, 在 css3 中, 媒體查詢的機(jī)制得到了補(bǔ)充. 并且除了 IE8 以外, 其他瀏覽器或者說, 手機(jī)端都是支持的. 他主要的用途還是區(qū)分  手機(jī)端,PC端, 屏幕的大小等.

屏幕大小

先看個(gè) demo:

<link rel="stylesheet"  media="only screen and (min-width: 641px) and (max-width: 800px)" href="ipad.css">

設(shè)置當(dāng)屏幕的大小為 [641,800]之間時(shí), 才加載 ipad.css. 如果, 不符合, 瀏覽器會(huì)默認(rèn)忽略這個(gè) tag. 其中 only 這個(gè)  flag 是非常重要的. 他主要作用就是告訴瀏覽器不符合則忽略的規(guī)則.

通過, 屏幕的大小來判斷 mobile , pad , PC 是比較有用的.

meta 標(biāo)簽

meta 主要用來設(shè)置網(wǎng)頁的源信息, 比如, 縮放, 寬度等等. 最常用的就是手機(jī)端上的

<meta content=" width=device-width;  // 網(wǎng)頁初始寬度和設(shè)備寬度一致 initial-scale=1.0;  // 初始放大效果 maximum-scale=1.0;  // ***放大效果 user-scalable=no"   // 防止用戶縮放 name="viewport" />   <meta content="yes" name="apple-mobile-web-app-capable" />  //允許全屏模式瀏覽 <meta content="telephone=no" name="format-detection" /> //忽略將屏幕中的數(shù)字識(shí)別為電話號(hào)碼;

這里只是整理了一些皮毛, 有興趣的同學(xué),可以參考另外兩篇文章:

  • 移動(dòng)web問題小結(jié)

  • 無線Web開發(fā)經(jīng)驗(yàn)談

后面如果遇到些比較坑的問題, 會(huì)及時(shí)更新的。

以上就是手機(jī)端Web開發(fā)中遇到的問題有哪些,小編相信有部分知識(shí)點(diǎn)可能是我們?nèi)粘9ぷ鲿?huì)見到或用到的。希望你能通過這篇文章學(xué)到更多知識(shí)。更多詳情敬請(qǐng)關(guān)注億速云行業(yè)資訊頻道。

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請(qǐng)聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

web
AI