Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537 Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537 欧美中文字幕一区二区三区,特黄日韩免费一区二区三区,久久精品一区

          整合營銷服務(wù)商

          電腦端+手機(jī)端+微信端=數(shù)據(jù)同步管理

          免費(fèi)咨詢熱線:

          如何使用JavaScript判斷手機(jī)是處于橫屏還是豎

          如何使用JavaScript判斷手機(jī)是處于橫屏還是豎屏狀態(tài)?orientation


          動(dòng)端的瀏覽器一般都支持window.orientation這個(gè)屬性,通過這個(gè)屬性可以判斷出手機(jī)是處在橫屏還是豎屏狀態(tài)。從而根據(jù)實(shí)際需求而執(zhí)行相應(yīng)的程序。通過添加監(jiān)聽事件onorientationchange就可以了。

          多朋友都遇到過需要把手機(jī)轉(zhuǎn)來轉(zhuǎn)去的情況,APP和游戲不能一起都保持橫屏或者豎屏。例如玩游戲看視頻的時(shí)候手機(jī)是強(qiáng)制橫屏的,然后來了一條信息,想要回信息切換到微信QQ,手機(jī)突然又豎屏了——就算在系統(tǒng)開啟了自動(dòng)旋轉(zhuǎn),微信QQ仍會(huì)強(qiáng)制豎屏顯示。如果你是躺在床上玩手機(jī),這特別不方便,有沒有什么解決辦法?這就給大家介紹一款可以控制所有APP屏幕方向的APP,連微信QQ都可以強(qiáng)制橫屏,再也不用將手機(jī)翻來覆去,一起來看看吧。

          屏幕旋轉(zhuǎn)

          這款A(yù)PP的名字叫做“Ultimate Rotation Control”,也就是終極屏幕控制的意思。開啟APP后,即可看到開啟服務(wù)的開關(guān),按照提示開啟即可。




          需要相應(yīng)的權(quán)限

          開啟了相應(yīng)的權(quán)限后,即可看到APP的各種功能。在主界面中個(gè),能夠找到使用何種旋轉(zhuǎn)方案(強(qiáng)制自動(dòng)、鎖定當(dāng)前、強(qiáng)制縱向/橫向等等),選擇你需要的方案就可以了。而如果不想要全局生效,那么也可以針對(duì)APP單獨(dú)進(jìn)行配置,這點(diǎn)還是不錯(cuò)的 。




          可以選擇全局屏幕旋轉(zhuǎn)方案



          可以為每個(gè)APP單獨(dú)設(shè)置選擇方案,也可以設(shè)置自動(dòng)觸發(fā)的方案,例如插入底座就自動(dòng)橫屏等

          那么這款屏幕控制APP的效果如何?廢話不多說,先來看下面的截圖!



          利用這APP設(shè)置橫屏后,桌面的布局很完美


          QQ也可以橫屏顯示


          微信橫屏也沒問題

          可以看到,開啟了強(qiáng)制屏幕旋轉(zhuǎn)后,就算是微信、QQ,也可以橫屏顯示!如此一來,玩游戲的時(shí)候回信息,就不用把手機(jī)轉(zhuǎn)來轉(zhuǎn)去,橫屏就可以完美操作了!

          這款屏幕控制APP既可以強(qiáng)制橫評(píng),也可以強(qiáng)制自動(dòng)旋轉(zhuǎn),當(dāng)然也可以強(qiáng)制豎屏。有的朋友可能會(huì)想,普通APP可以強(qiáng)制橫屏,效果非常好,那么游戲能不能強(qiáng)制豎屏?的確可以,但是顯示就沒那么完美了。因?yàn)橛螒蚝虯PP不同,很多素材都是固定顯示的,不能像APP那樣UI自適配屏幕長寬,因此大家想要統(tǒng)一屏幕方向,還是強(qiáng)制橫屏兼容性更高。



          游戲的話很有可能顯示不全

          不得不說,這款屏幕控制APP的效果的確非常好,而如果你想要快捷切換屏幕旋轉(zhuǎn)方案,也只需要下拉狀態(tài)欄從通知中心直接控制即可,用著還是很便利的。


          下載鏈接:http://dl.pconline.com.cn/download/2029796.html

          在通知中心直接就可以切換屏幕旋轉(zhuǎn)方案

          總的來說,這的確是一款實(shí)用性十足的APP,完全可以用來取代系統(tǒng)本身的屏幕方向控制功能。如果你有這方面的需求,不妨嘗試一下吧!

          移動(dòng)端適配,是我們?cè)陂_發(fā)中經(jīng)常會(huì)遇到的,這里面可能會(huì)遇到非常多的問題:

          • 1px問題
          • UI圖完美適配方案
          • iPhoneX適配方案
          • 橫屏適配
          • 高清屏圖片模糊問題
          • ...

          上面這些問題可能我們?cè)陂_發(fā)中已經(jīng)知道如何解決,但是問題產(chǎn)生的原理,以及解決方案的原理可能會(huì)模糊不清。在解決這些問題的過程中,我們往往會(huì)遇到非常多的概念:像素、分辨率、PPI、DPI、DP、DIP、DPR、視口等等,你真的能分清這些概念的意義嗎?

          本文將從移動(dòng)端適配的基礎(chǔ)概念出發(fā),探究移動(dòng)端適配各種問題的解決方案和實(shí)現(xiàn)原理。

          一、英寸

          一般用英寸描述屏幕的物理大小,如電腦顯示器的17、22,手機(jī)顯示器的4.8、5.7等使用的單位都是英寸。

          需要注意,上面的尺寸都是屏幕對(duì)角線的長度:

          英寸(inch,縮寫為in)在荷蘭語中的本意是大拇指,一英寸就是指甲底部普通人拇指的寬度。

          英寸和厘米的換算:1英寸=2.54 厘米

          二、分辨率

          2.1 像素

          像素即一個(gè)小方塊,它具有特定的位置和顏色。

          圖片、電子屏幕(手機(jī)、電腦)就是由無數(shù)個(gè)具有特定顏色和特定位置的小方塊拼接而成。

          像素可以作為圖片或電子屏幕的最小組成單位。

          下面我們使用sketch打開一張圖片:

          將這些圖片放大即可看到這些像素點(diǎn):

          通常我們所說的分辨率有兩種,屏幕分辨率和圖像分辨率。

          2.2 屏幕分辨率

          屏幕分辨率指一個(gè)屏幕具體由多少個(gè)像素點(diǎn)組成。

          下面是apple的官網(wǎng)上對(duì)手機(jī)分辨率的描述:

          iPhone XS Max 和 iPhone SE的分辨率分別為2688 x 1242和1136 x 640。這表示手機(jī)分別在垂直和水平上所具有的像素點(diǎn)數(shù)。

          當(dāng)然分辨率高不代表屏幕就清晰,屏幕的清晰程度還與尺寸有關(guān)。

          2.3 圖像分辨率

          我們通常說的圖片分辨率其實(shí)是指圖片含有的像素?cái)?shù),比如一張圖片的分辨率為800 x 400。這表示圖片分別在垂直和水平上所具有的像素點(diǎn)數(shù)為800和400。

          同一尺寸的圖片,分辨率越高,圖片越清晰。

          2.4 PPI

          PPI(Pixel Per Inch):每英寸包括的像素?cái)?shù)。

          PPI可以用于描述屏幕的清晰度以及一張圖片的質(zhì)量。

          使用PPI描述圖片時(shí),PPI越高,圖片質(zhì)量越高,使用PPI描述屏幕時(shí),PPI越高,屏幕越清晰。

          在上面描述手機(jī)分辨率的圖片中,我們可以看到:iPhone XS Max 和 iPhone SE的PPI分別為458和326,這足以證明前者的屏幕更清晰。

          由于手機(jī)尺寸為手機(jī)對(duì)角線的長度,我們通常使用如下的方法計(jì)算PPI:

          iPhone 6的PPI為

          ,那它每英寸約含有326個(gè)物理像素點(diǎn)。

          2.5 DPI

          DPI(Dot Per Inch):即每英寸包括的點(diǎn)數(shù)。

          這里的點(diǎn)是一個(gè)抽象的單位,它可以是屏幕像素點(diǎn)、圖片像素點(diǎn)也可以是打印機(jī)的墨點(diǎn)。

          平時(shí)你可能會(huì)看到使用DPI來描述圖片和屏幕,這時(shí)的DPI應(yīng)該和PPI是等價(jià)的,DPI最常用的是用于描述打印機(jī),表示打印機(jī)每英寸可以打印的點(diǎn)數(shù)。

          一張圖片在屏幕上顯示時(shí),它的像素點(diǎn)數(shù)是規(guī)則排列的,每個(gè)像素點(diǎn)都有特定的位置和顏色。

          當(dāng)使用打印機(jī)進(jìn)行打印時(shí),打印機(jī)可能不會(huì)規(guī)則的將這些點(diǎn)打印出來,而是使用一個(gè)個(gè)打印點(diǎn)來呈現(xiàn)這張圖像,這些打印點(diǎn)之間會(huì)有一定的空隙,這就是DPI所描述的:打印點(diǎn)的密度。

          在上面的圖像中我們可以清晰的看到,打印機(jī)是如何使用墨點(diǎn)來打印一張圖像。

          所以,打印機(jī)的DPI越高,打印圖像的精細(xì)程度就越高,同時(shí)這也會(huì)消耗更多的墨點(diǎn)和時(shí)間。

          三、設(shè)備獨(dú)立像素

          實(shí)際上,上面我們描述的像素都是物理像素,即設(shè)備上真實(shí)的物理單元。

          下面我們來看看設(shè)備獨(dú)立像素究竟是如何產(chǎn)生的:

          智能手機(jī)發(fā)展非常之快,在幾年之前,我們還用著分辨率非常低的手機(jī),比如下面左側(cè)的白色手機(jī),它的分辨率是320x480,我們可以在上面瀏覽正常的文字、圖片等等。

          但是,隨著科技的發(fā)展,低分辨率的手機(jī)已經(jīng)不能滿足我們的需求了。很快,更高分辨率的屏幕誕生了,比如下面的黑色手機(jī),它的分辨率是640x940,正好是白色手機(jī)的兩倍。

          理論上來講,在白色手機(jī)上相同大小的圖片和文字,在黑色手機(jī)上會(huì)被縮放一倍,因?yàn)樗姆直媛侍岣吡艘槐丁_@樣,豈不是后面出現(xiàn)更高分辨率的手機(jī),頁面元素會(huì)變得越來越小嗎?

          然而,事實(shí)并不是這樣的,我們現(xiàn)在使用的智能手機(jī),不管分辨率多高,他們所展示的界面比例都是基本類似的。喬布斯在iPhone4的發(fā)布會(huì)上首次提出了Retina Display(視網(wǎng)膜屏幕)的概念,它正是解決了上面的問題,這也使它成為一款跨時(shí)代的手機(jī)。

          在iPhone4使用的視網(wǎng)膜屏幕中,把2x2個(gè)像素當(dāng)1個(gè)像素使用,這樣讓屏幕看起來更精致,但是元素的大小卻不會(huì)改變。

          如果黑色手機(jī)使用了視網(wǎng)膜屏幕的技術(shù),那么顯示結(jié)果應(yīng)該是下面的情況,比如列表的寬度為300個(gè)像素,那么在一條水平線上,白色手機(jī)會(huì)用300個(gè)物理像素去渲染它,而黑色手機(jī)實(shí)際上會(huì)用600個(gè)物理像素去渲染它。

          我們必須用一種單位來同時(shí)告訴不同分辨率的手機(jī),它們?cè)诮缑嫔巷@示元素的大小是多少,這個(gè)單位就是設(shè)備獨(dú)立像素(Device Independent Pixels)簡(jiǎn)稱DIP或DP。上面我們說,列表的寬度為300個(gè)像素,實(shí)際上我們可以說:列表的寬度為300個(gè)設(shè)備獨(dú)立像素。

          打開chrome的開發(fā)者工具,我們可以模擬各個(gè)手機(jī)型號(hào)的顯示情況,每種型號(hào)上面會(huì)顯示一個(gè)尺寸,比如iPhone X顯示的尺寸是375x812,實(shí)際iPhone X的分辨率會(huì)比這高很多,這里顯示的就是設(shè)備獨(dú)立像素。

          3.1 設(shè)備像素比

          設(shè)備像素比device pixel ratio簡(jiǎn)稱dpr,即物理像素和設(shè)備獨(dú)立像素的比值。

          在web中,瀏覽器為我們提供了window.devicePixelRatio來幫助我們獲取dpr。

          在css中,可以使用媒體查詢min-device-pixel-ratio,區(qū)分dpr:

          @media (-webkit-min-device-pixel-ratio: 2),(min-device-pixel-ratio: 2){ }
          
          

          在React Native中,我們也可以使用PixelRatio.get()來獲取DPR。

          當(dāng)然,上面的規(guī)則也有例外,iPhone 6、7、8 Plus的實(shí)際物理像素是1080 x 1920,在開發(fā)者工具中我們可以看到:它的設(shè)備獨(dú)立像素是414 x 736,設(shè)備像素比為3,設(shè)備獨(dú)立像素和設(shè)備像素比的乘積并不等于1080 x 1920,而是等于1242 x 2208。

          實(shí)際上,手機(jī)會(huì)自動(dòng)把1242 x 2208個(gè)像素點(diǎn)塞進(jìn)1080 * 1920個(gè)物理像素點(diǎn)來渲染,我們不用關(guān)心這個(gè)過程,而1242 x 2208被稱為屏幕的設(shè)計(jì)像素。我們開發(fā)過程中也是以這個(gè)設(shè)計(jì)像素為準(zhǔn)。

          實(shí)際上,從蘋果提出視網(wǎng)膜屏幕開始,才出現(xiàn)設(shè)備像素比這個(gè)概念,因?yàn)樵谶@之前,移動(dòng)設(shè)備都是直接使用物理像素來進(jìn)行展示。

          緊接著,Android同樣使用了其他的技術(shù)方案來實(shí)現(xiàn)DPR大于1的屏幕,不過原理是類似的。由于Android屏幕尺寸非常多、分辨率高低跨度非常大,不像蘋果只有它自己的幾款固定設(shè)備、尺寸。所以,為了保證各種設(shè)備的顯示效果,Android按照設(shè)備的像素密度將設(shè)備分成了幾個(gè)區(qū)間:

          當(dāng)然,所有的Android設(shè)備不一定嚴(yán)格按照上面的分辨率,每個(gè)類型可能對(duì)應(yīng)幾種不同分辨率,所以,每個(gè)Android手機(jī)都能根據(jù)給定的區(qū)間范圍,確定自己的DPR,從而擁有類似的顯示。當(dāng)然,僅僅是類似,由于各個(gè)設(shè)備的尺寸、分辨率上的差異,設(shè)備獨(dú)立像素也不會(huì)完全相等,所以各種Android設(shè)備仍然不能做到在展示上完全相等。

          3.2 移動(dòng)端開發(fā)

          在iOS、Android和React Native開發(fā)中樣式單位其實(shí)都使用的是設(shè)備獨(dú)立像素。

          iOS的尺寸單位為pt,Android的尺寸單位為dp,React Native中沒有指定明確的單位,它們其實(shí)都是設(shè)備獨(dú)立像素dp。

          在使用React Native開發(fā)App時(shí),UI給我們的原型圖一般是基于iphone6的像素給定的。

          為了適配所有機(jī)型,我們?cè)趯憳邮綍r(shí)需要把物理像素轉(zhuǎn)換為設(shè)備獨(dú)立像素:例如:如果給定一個(gè)元素的高度為200px(這里的px指物理像素,非CSS像素),iphone6的設(shè)備像素比為2,我們給定的height應(yīng)為200px/2=100dp。

          當(dāng)然,最好的是,你可以和設(shè)計(jì)溝通好,所有的UI圖都按照設(shè)備獨(dú)立像素來出。

          我們還可以在代碼(React Native)中進(jìn)行px和dp的轉(zhuǎn)換:

          import {PixelRatio } from 'react-native';
          const dpr=PixelRatio.get();
          /**
           * px轉(zhuǎn)換為dp
           */
          export function pxConvertTodp(px) {
           return px / dpr;
          }
          /**
           * dp轉(zhuǎn)換為px
           */
          export function dpConvertTopx(dp) {
           return PixelRatio.getPixelSizeForLayoutSize(dp);
          }
          

          3.3 WEB端開發(fā)

          在寫CSS時(shí),我們用到最多的單位是px,即CSS像素,當(dāng)頁面縮放比例為100%時(shí),一個(gè)CSS像素等于一個(gè)設(shè)備獨(dú)立像素。

          但是CSS像素是很容易被改變的,當(dāng)用戶對(duì)瀏覽器進(jìn)行了放大,CSS像素會(huì)被放大,這時(shí)一個(gè)CSS像素會(huì)跨越更多的物理像素。

          頁面的縮放系數(shù)=CSS像素 / 設(shè)備獨(dú)立像素。

          3.4 關(guān)于屏幕

          這里多說兩句Retina屏幕,因?yàn)槲以诤芏辔恼轮锌吹綄?duì)Retina屏幕的誤解。

          Retina屏幕只是蘋果提出的一個(gè)營銷術(shù)語:

          在普通的使用距離下,人的肉眼無法分辨單個(gè)的像素點(diǎn)。

          為什么強(qiáng)調(diào)普通的使用距離下呢?我們來看一下它的計(jì)算公式:

          a代表人眼視角,h代表像素間距,d代表肉眼與屏幕的距離,符合以上條件的屏幕可以使肉眼看不見單個(gè)物理像素點(diǎn)。

          它不能單純的表達(dá)分辨率和PPI,只能一種表達(dá)視覺效果。

          讓多個(gè)物理像素渲染一個(gè)獨(dú)立像素只是Retina屏幕為了達(dá)到效果而使用的一種技術(shù)。而不是所有DPR > 1的屏幕就是Retina屏幕。

          比如:給你一塊超大尺寸的屏幕,即使它的PPI很高,DPR也很高,在近距離你也能看清它的像素點(diǎn),這就不算Retina屏幕。

          我們經(jīng)常見到用K和P這個(gè)單位來形容屏幕:

          P代表的就是屏幕縱向的像素個(gè)數(shù),1080P即縱向有1080個(gè)像素,分辨率為1920X1080的屏幕就屬于1080P屏幕。

          我們平時(shí)所說的高清屏其實(shí)就是屏幕的物理分辨率達(dá)到或超過1920X1080的屏幕。

          K代表屏幕橫向有幾個(gè)1024個(gè)像素,一般來講橫向像素超過2048就屬于2K屏,橫向像素超過4096就屬于4K屏。

          四、視口

          視口(viewport)代表當(dāng)前可見的計(jì)算機(jī)圖形區(qū)域。在Web瀏覽器術(shù)語中,通常與瀏覽器窗口相同,但不包括瀏覽器的UI, 菜單欄等——即指你正在瀏覽的文檔的那一部分。

          一般我們所說的視口共包括三種:布局視口、視覺視口和理想視口,它們?cè)谄聊贿m配中起著非常重要的作用。

          4.1 布局視口

          布局視口(layout viewport):當(dāng)我們以百分比來指定一個(gè)元素的大小時(shí),它的計(jì)算值是由這個(gè)元素的包含塊計(jì)算而來的。當(dāng)這個(gè)元素是最頂級(jí)的元素時(shí),它就是基于布局視口來計(jì)算的。

          所以,布局視口是網(wǎng)頁布局的基準(zhǔn)窗口,在PC瀏覽器上,布局視口就等于當(dāng)前瀏覽器的窗口大小(不包括borders 、margins、滾動(dòng)條)。

          在移動(dòng)端,布局視口被賦予一個(gè)默認(rèn)值,大部分為980px,這保證PC的網(wǎng)頁可以在手機(jī)瀏覽器上呈現(xiàn),但是非常小,用戶可以手動(dòng)對(duì)網(wǎng)頁進(jìn)行放大。

          我們可以通過調(diào)用document.documentElement.clientWidth / clientHeight來獲取布局視口大小。

          4.2 視覺視口

          視覺視口(visual viewport):用戶通過屏幕真實(shí)看到的區(qū)域。

          視覺視口默認(rèn)等于當(dāng)前瀏覽器的窗口大小(包括滾動(dòng)條寬度)。

          當(dāng)用戶對(duì)瀏覽器進(jìn)行縮放時(shí),不會(huì)改變布局視口的大小,所以頁面布局是不變的,但是縮放會(huì)改變視覺視口的大小。

          例如:用戶將瀏覽器窗口放大了200%,這時(shí)瀏覽器窗口中的CSS像素會(huì)隨著視覺視口的放大而放大,這時(shí)一個(gè)CSS像素會(huì)跨越更多的物理像素。

          所以,布局視口會(huì)限制你的CSS布局而視覺視口決定用戶具體能看到什么。

          我們可以通過調(diào)用window.innerWidth / innerHeight來獲取視覺視口大小。

          4.3 理想視口

          布局視口在移動(dòng)端展示的效果并不是一個(gè)理想的效果,所以理想視口(ideal viewport)就誕生了:網(wǎng)站頁面在移動(dòng)端展示的理想大小。

          如上圖,我們?cè)诿枋鲈O(shè)備獨(dú)立像素時(shí)曾使用過這張圖,在瀏覽器調(diào)試移動(dòng)端時(shí)頁面上給定的像素大小就是理想視口大小,它的單位正是設(shè)備獨(dú)立像素。

          上面在介紹CSS像素時(shí)曾經(jīng)提到頁面的縮放系數(shù)=CSS像素 / 設(shè)備獨(dú)立像素,實(shí)際上說頁面的縮放系數(shù)=理想視口寬度 / 視覺視口寬度更為準(zhǔn)確。

          所以,當(dāng)頁面縮放比例為100%時(shí),CSS像素=設(shè)備獨(dú)立像素,理想視口=視覺視口。

          我們可以通過調(diào)用screen.width / height來獲取理想視口大小。

          4.4 Meta viewport

          <meta> 元素表示那些不能由其它HTML元相關(guān)元素之一表示的任何元數(shù)據(jù)信息,它可以告訴瀏覽器如何解析頁面。

          我們可以借助<meta>元素的viewport來幫助我們?cè)O(shè)置視口、縮放等,從而讓移動(dòng)端得到更好的展示效果。

          <meta name="viewport" content="width=device-width; initial-scale=1; maximum-scale=1; minimum-scale=1; user-scalable=no;">
          
          

          上面是viewport的一個(gè)配置,我們來看看它們的具體含義:

          Value 可能值 描述 width 正整數(shù)或device-width 以pixels(像素)為單位, 定義布局視口的寬度。 height 正整數(shù)或device-height 以pixels(像素)為單位, 定義布局視口的高度。 initial-scale 0.0 - 10.0 定義頁面初始縮放比率。 minimum-scale 0.0 - 10.0 定義縮放的最小值;必須小于或等于maximum-scale的值。 maximum-scale 0.0 - 10.0 定義縮放的最大值;必須大于或等于minimum-scale的值。 user-scalable 一個(gè)布爾值(yes或者no) 如果設(shè)置為 no,用戶將不能放大或縮小網(wǎng)頁。默認(rèn)值為 yes。 4.5 移動(dòng)端適配

          為了在移動(dòng)端讓頁面獲得更好的顯示效果,我們必須讓布局視口、視覺視口都盡可能等于理想視口。

          device-width就等于理想視口的寬度,所以設(shè)置width=device-width就相當(dāng)于讓布局視口等于理想視口。

          由于initial-scale=理想視口寬度 / 視覺視口寬度,所以我們?cè)O(shè)置initial-scale=1;就相當(dāng)于讓視覺視口等于理想視口。

          這時(shí),1個(gè)CSS像素就等于1個(gè)設(shè)備獨(dú)立像素,而且我們也是基于理想視口來進(jìn)行布局的,所以呈現(xiàn)出來的頁面布局在各種設(shè)備上都能大致相似。

          4.6 縮放

          上面提到width可以決定布局視口的寬度,實(shí)際上它并不是布局視口的唯一決定性因素,設(shè)置initial-scale也有肯能影響到布局視口,因?yàn)椴季忠暱趯挾热〉氖莣idth和視覺視口寬度的最大值。

          例如:若手機(jī)的理想視口寬度為400px,設(shè)置width=device-width,initial-scale=2,此時(shí)視覺視口寬度=理想視口寬度 / initial-scale即200px,布局視口取兩者最大值即device-width 400px。

          若設(shè)置width=device-width,initial-scale=0.5,此時(shí)視覺視口寬度=理想視口寬度 / initial-scale即800px,布局視口取兩者最大值即800px。

          4.7 獲取瀏覽器大小

          瀏覽器為我們提供的獲取窗口大小的API有很多,下面我們?cè)賮韺?duì)比一下:

          • window.innerHeight:獲取瀏覽器視覺視口高度(包括垂直滾動(dòng)條)。
          • window.outerHeight:獲取瀏覽器窗口外部的高度。表示整個(gè)瀏覽器窗口的高度,包括側(cè)邊欄、窗口鑲邊和調(diào)正窗口大小的邊框。
          • window.screen.Height:獲取獲屏幕取理想視口高度,這個(gè)數(shù)值是固定的,設(shè)備的分辨率/設(shè)備像素比
          • window.screen.availHeight:瀏覽器窗口可用的高度。
          • document.documentElement.clientHeight:獲取瀏覽器布局視口高度,包括內(nèi)邊距,但不包括垂直滾動(dòng)條、邊框和外邊距。
          • document.documentElement.offsetHeight:包括內(nèi)邊距、滾動(dòng)條、邊框和外邊距。
          • document.documentElement.scrollHeight:在不使用滾動(dòng)條的情況下適合視口中的所有內(nèi)容所需的最小寬度。測(cè)量方式與clientHeight相同:它包含元素的內(nèi)邊距,但不包括邊框,外邊距或垂直滾動(dòng)條。

          五、1px問題

          為了適配各種屏幕,我們寫代碼時(shí)一般使用設(shè)備獨(dú)立像素來對(duì)頁面進(jìn)行布局。

          而在設(shè)備像素比大于1的屏幕上,我們寫的1px實(shí)際上是被多個(gè)物理像素渲染,這就會(huì)出現(xiàn)1px在有些屏幕上看起來很粗的現(xiàn)象。

          5.1 border-image

          基于media查詢判斷不同的設(shè)備像素比給定不同的border-image:

           .border_1px{
           border-bottom: 1px solid #000;
           }
           @media only screen and (-webkit-min-device-pixel-ratio:2){
           .border_1px{
           border-bottom: none;
           border-width: 0 0 1px 0;
           border-image: url(../img/1pxline.png) 0 0 2 0 stretch;
           }
           }
          

          5.2 background-image

          和border-image類似,準(zhǔn)備一張符合條件的邊框背景圖,模擬在背景上。

           .border_1px{
           border-bottom: 1px solid #000;
           }
           @media only screen and (-webkit-min-device-pixel-ratio:2){
           .border_1px{
           background: url(../img/1pxline.png) repeat-x left bottom;
           background-size: 100% 1px;
           }
           }
          

          上面兩種都需要單獨(dú)準(zhǔn)備圖片,而且圓角不是很好處理,但是可以應(yīng)對(duì)大部分場(chǎng)景。

          5.3 偽類 + transform

          基于media查詢判斷不同的設(shè)備像素比對(duì)線條進(jìn)行縮放:

           .border_1px:before{
           content: '';
           position: absolute;
           top: 0;
           height: 1px;
           width: 100%;
           background-color: #000;
           transform-origin: 50% 0%;
           }
           @media only screen and (-webkit-min-device-pixel-ratio:2){
           .border_1px:before{
           transform: scaleY(0.5);
           }
           }
           @media only screen and (-webkit-min-device-pixel-ratio:3){
           .border_1px:before{
           transform: scaleY(0.33);
           }
           }
          

          這種方式可以滿足各種場(chǎng)景,如果需要滿足圓角,只需要給偽類也加上border-radius即可。

          5.4 svg

          上面我們border-image和background-image都可以模擬1px邊框,但是使用的都是位圖,還需要外部引入。

          借助PostCSS的postcss-write-svg我們能直接使用border-image和background-image創(chuàng)建svg的1px邊框:

          @svg border_1px { 
           height: 2px; 
           @rect { 
           fill: var(--color, black); 
           width: 100%; 
           height: 50%; 
           } 
           } 
          .example { border: 1px solid transparent; border-image: svg(border_1px param(--color #00b1ff)) 2 2 stretch; }
          

          編譯后:

          .example { border: 1px solid transparent; border-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' height='2px'%3E%3Crect fill='%2300b1ff' width='100%25' height='50%25'/%3E%3C/svg%3E") 2 2 stretch; }
          

          上面的方案是大漠在他的文章中推薦使用的,基本可以滿足所有場(chǎng)景,而且不需要外部引入,這是我個(gè)人比較喜歡的一種方案。

          5.5 設(shè)置viewport

          通過設(shè)置縮放,讓CSS像素等于真正的物理像素。

          例如:當(dāng)設(shè)備像素比為3時(shí),我們將頁面縮放1/3倍,這時(shí)1px等于一個(gè)真正的屏幕像素。

           const scale=1 / window.devicePixelRatio;
           const viewport=document.querySelector('meta[name="viewport"]');
           if (!viewport) {
           viewport=document.createElement('meta');
           viewport.setAttribute('name', 'viewport');
           window.document.head.appendChild(viewport);
           }
           viewport.setAttribute('content', 'width=device-width,user-scalable=no,initial-scale=' + scale + ',maximum-scale=' + scale + ',minimum-scale=' + scale);
          
          

          實(shí)際上,上面這種方案是早先flexible采用的方案。

          當(dāng)然,這樣做是要付出代價(jià)的,這意味著你頁面上所有的布局都要按照物理像素來寫。這顯然是不現(xiàn)實(shí)的,這時(shí),我們可以借助flexible或vw、vh來幫助我們進(jìn)行適配。

          六、移動(dòng)端適配方案

          盡管我們可以使用設(shè)備獨(dú)立像素來保證各個(gè)設(shè)備在不同手機(jī)上顯示的效果類似,但這并不能保證它們顯示完全一致,我們需要一種方案來讓設(shè)計(jì)稿得到更完美的適配。

          6.1 flexible方案

          flexible方案是阿里早期開源的一個(gè)移動(dòng)端適配解決方案,引用flexible后,我們?cè)陧撁嫔辖y(tǒng)一使用rem來布局。

          它的核心代碼非常簡(jiǎn)單:

          // set 1rem=viewWidth / 10
          function setRemUnit () {
           var rem=docEl.clientWidth / 10
           docEl.style.fontSize=rem + 'px'
          }
          setRemUnit();
          
          

          rem 是相對(duì)于html節(jié)點(diǎn)的font-size來做計(jì)算的。

          我們通過設(shè)置document.documentElement.style.fontSize就可以統(tǒng)一整個(gè)頁面的布局標(biāo)準(zhǔn)。

          上面的代碼中,將html節(jié)點(diǎn)的font-size設(shè)置為頁面clientWidth(布局視口)的1/10,即1rem就等于頁面布局視口的1/10,這就意味著我們后面使用的rem都是按照頁面比例來計(jì)算的。

          這時(shí),我們只需要將UI出的圖轉(zhuǎn)換為rem即可。

          以iPhone6為例:布局視口為375px,則1rem=37.5px,這時(shí)UI給定一個(gè)元素的寬為75px(設(shè)備獨(dú)立像素),我們只需要將它設(shè)置為75 / 37.5=2rem。

          當(dāng)然,每個(gè)布局都要計(jì)算非常繁瑣,我們可以借助PostCSS的px2rem插件來幫助我們完成這個(gè)過程。

          下面的代碼可以保證在頁面大小變化時(shí),布局可以自適應(yīng),當(dāng)觸發(fā)了window的resize和pageShow事件之后自動(dòng)調(diào)整html的fontSize大小。

           // reset rem unit on page resize
          window.addEventListener('resize', setRemUnit)window.addEventListener('pageshow', function (e) {
           if (e.persisted) {
           setRemUnit()
           }
          })
          
          

          由于viewport單位得到眾多瀏覽器的兼容,上面這種方案現(xiàn)在已經(jīng)被官方棄用:

          lib-flexible這個(gè)過渡方案已經(jīng)可以放棄使用,不管是現(xiàn)在的版本還是以前的版本,都存有一定的問題。建議大家開始使用viewport來替代此方案。

          下面我們來看看現(xiàn)在最流行的vh、vw方案。

          6.2 vh、vw方案

          vh、vw方案即將視覺視口寬度 window.innerWidth和視覺視口高度 window.innerHeight 等分為 100 份。

          上面的flexible方案就是模仿這種方案,因?yàn)樵缧r(shí)候vw還沒有得到很好的兼容。

          • vw(Viewport's width):1vw等于視覺視口的1%
          • vh(Viewport's height) :1vh 為視覺視口高度的1%
          • vmin : vw 和 vh 中的較小值
          • vmax : 選取 vw 和 vh 中的較大值

          如果視覺視口為375px,那么1vw=3.75px,這時(shí)UI給定一個(gè)元素的寬為75px(設(shè)備獨(dú)立像素),我們只需要將它設(shè)置為75 / 3.75=20vw。

          這里的比例關(guān)系我們也不用自己換算,我們可以使用PostCSS的 postcss-px-to-viewport 插件幫我們完成這個(gè)過程。寫代碼時(shí),我們只需要根據(jù)UI給的設(shè)計(jì)圖寫px單位即可。

          當(dāng)然,沒有一種方案是十全十美的,vw同樣有一定的缺陷:

          • px轉(zhuǎn)換成vw不一定能完全整除,因此有一定的像素差。
          • 比如當(dāng)容器使用vw,margin采用px時(shí),很容易造成整體寬度超過100vw,從而影響布局效果。當(dāng)然我們也是可以避免的,例如使用padding代替margin,結(jié)合calc()函數(shù)使用等等...

          七、適配iPhoneX

          iPhoneX的出現(xiàn)將手機(jī)的顏值帶上了一個(gè)新的高度,它取消了物理按鍵,改成了底部的小黑條,但是這樣的改動(dòng)給開發(fā)者適配移動(dòng)端又增加了難度。

          7.1 安全區(qū)域

          在iPhoneX發(fā)布后,許多廠商相繼推出了具有邊緣屏幕的手機(jī)。

          這些手機(jī)和普通手機(jī)在外觀上無外乎做了三個(gè)改動(dòng):圓角(corners)、劉海(sensor housing)和小黑條(Home Indicator)。為了適配這些手機(jī),安全區(qū)域這個(gè)概念變誕生了:安全區(qū)域就是一個(gè)不受上面三個(gè)效果的可視窗口范圍。

          為了保證頁面的顯示效果,我們必須把頁面限制在安全范圍內(nèi),但是不影響整體效果。

          7.2 viewport-fit

          viewport-fit是專門為了適配iPhoneX而誕生的一個(gè)屬性,它用于限制網(wǎng)頁如何在安全區(qū)域內(nèi)進(jìn)行展示。

          contain: 可視窗口完全包含網(wǎng)頁內(nèi)容

          cover:網(wǎng)頁內(nèi)容完全覆蓋可視窗口

          默認(rèn)情況下或者設(shè)置為auto和contain效果相同。

          7.3 env、constant

          我們需要將頂部和底部合理的擺放在安全區(qū)域內(nèi),iOS11新增了兩個(gè)CSS函數(shù)env、constant,用于設(shè)定安全區(qū)域與邊界的距離。

          函數(shù)內(nèi)部可以是四個(gè)常量:

          • safe-area-inset-left:安全區(qū)域距離左邊邊界距離
          • safe-area-inset-right:安全區(qū)域距離右邊邊界距離
          • safe-area-inset-top:安全區(qū)域距離頂部邊界距離
          • safe-area-inset-bottom:安全區(qū)域距離底部邊界距離

          注意:我們必須指定viweport-fit后才能使用這兩個(gè)函數(shù):

          <meta name="viewport" content="viewport-fit=cover">
          
          

          constant在iOS < 11.2的版本中生效,env在iOS >=11.2的版本中生效,這意味著我們往往要同時(shí)設(shè)置他們,將頁面限制在安全區(qū)域內(nèi):

          body {
           padding-bottom: constant(safe-area-inset-bottom);
           padding-bottom: env(safe-area-inset-bottom);
          }
          
          

          當(dāng)使用底部固定導(dǎo)航欄時(shí),我們要為他們?cè)O(shè)置padding值:

          {
           padding-bottom: constant(safe-area-inset-bottom);
           padding-bottom: env(safe-area-inset-bottom);
          }
          
          

          八、橫屏適配

          很多視口我們要對(duì)橫屏和豎屏顯示不同的布局,所以我們需要檢測(cè)在不同的場(chǎng)景下給定不同的樣式:

          8.1 JavaScript檢測(cè)橫屏

          window.orientation:獲取屏幕旋轉(zhuǎn)方向

          window.addEventListener("resize", ()=>{
           if (window.orientation===180 || window.orientation===0) { 
           // 正常方向或屏幕旋轉(zhuǎn)180度
           console.log('豎屏');
           };
           if (window.orientation===90 || window.orientation===-90 ){ 
           // 屏幕順時(shí)鐘旋轉(zhuǎn)90度或屏幕逆時(shí)針旋轉(zhuǎn)90度
           console.log('橫屏');
           } 
          }); 
          
          

          8.2 CSS檢測(cè)橫屏

          @media screen and (orientation: portrait) {
           /*豎屏...*/
          } 
          @media screen and (orientation: landscape) {
           /*橫屏...*/
          }
          
          

          九、圖片模糊問題

          9.1 產(chǎn)生原因

          我們平時(shí)使用的圖片大多數(shù)都屬于位圖(png、jpg...),位圖由一個(gè)個(gè)像素點(diǎn)構(gòu)成的,每個(gè)像素都具有特定的位置和顏色值:

          理論上,位圖的每個(gè)像素對(duì)應(yīng)在屏幕上使用一個(gè)物理像素來渲染,才能達(dá)到最佳的顯示效果。

          而在dpr > 1的屏幕上,位圖的一個(gè)像素可能由多個(gè)物理像素來渲染,然而這些物理像素點(diǎn)并不能被準(zhǔn)確的分配上對(duì)應(yīng)位圖像素的顏色,只能取近似值,所以相同的圖片在dpr > 1的屏幕上就會(huì)模糊:

          9.2 解決方案

          為了保證圖片質(zhì)量,我們應(yīng)該盡可能讓一個(gè)屏幕像素來渲染一個(gè)圖片像素,所以,針對(duì)不同DPR的屏幕,我們需要展示不同分辨率的圖片。

          如:在dpr=2的屏幕上展示兩倍圖(@2x),在dpr=3的屏幕上展示三倍圖(@3x)。

          9.3 media查詢

          使用media查詢判斷不同的設(shè)備像素比來顯示不同精度的圖片:

           .avatar{
           background-image: url(conardLi_1x.png);
           }
           @media only screen and (-webkit-min-device-pixel-ratio:2){
           .avatar{
           background-image: url(conardLi_2x.png);
           }
           }
           @media only screen and (-webkit-min-device-pixel-ratio:3){
           .avatar{
           background-image: url(conardLi_3x.png);
           }
           }
          
          

          只適用于背景圖

          9.4 image-set

          使用image-set:

          .avatar {
           background-image: -webkit-image-set( "conardLi_1x.png" 1x, "conardLi_2x.png" 2x );
          }
          
          

          只適用于背景圖

          9.5 srcset

          使用img標(biāo)簽的srcset屬性,瀏覽器會(huì)自動(dòng)根據(jù)像素密度匹配最佳顯示圖片:

          <img src="conardLi_1x.png"
           srcset=" conardLi_2x.png 2x, conardLi_3x.png 3x">
          
          

          9.6 JavaScript拼接圖片url

          使用window.devicePixelRatio獲取設(shè)備像素比,遍歷所有圖片,替換圖片地址:

          const dpr=window.devicePixelRatio;
          const images=document.querySelectorAll('img');
          images.forEach((img)=>{
           img.src.replace(".", `@${dpr}x.`);
          })
          
          

          9.7 使用svg

          SVG的全稱是可縮放矢量圖(Scalable Vector Graphics)。不同于位圖的基于像素,SVG 則是屬于對(duì)圖像的形狀描述,所以它本質(zhì)上是文本文件,體積較小,且不管放大多少倍都不會(huì)失真。

          除了我們手動(dòng)在代碼中繪制svg,我們還可以像使用位圖一樣使用svg圖片:

          <img src="conardLi.svg">
          <img src="data:image/svg+xml;base64,[data]">
          .avatar {
           background: url(conardLi.svg);
          }
          

          作者:ConardLi

          鏈接:https://juejin.im/post/5cddf289f265da038f77696c

          來源:掘金


          主站蜘蛛池模板: 无码毛片视频一区二区本码| 视频一区二区中文字幕| 日韩av片无码一区二区不卡电影| 日韩一区二区三区在线| 国产福利精品一区二区| 一区二区三区免费视频观看 | 极品尤物一区二区三区| 日本精品一区二区三区在线视频一 | 国产一区二区三区小向美奈子| 中日av乱码一区二区三区乱码| 国产成人一区二区三区电影网站 | 国产成人久久一区二区三区| 中文字幕乱码一区久久麻豆樱花| 熟女大屁股白浆一区二区| 一区二区三区四区在线播放 | 国产激情无码一区二区| 国产福利电影一区二区三区,日韩伦理电影在线福 | 亚洲AV无码一区二区二三区软件 | 香蕉免费一区二区三区 | 国产日韩综合一区二区性色AV| 亚洲综合色一区二区三区| 日韩精品区一区二区三VR| 精品少妇一区二区三区视频| 人妻少妇精品一区二区三区| 国产一区三区三区| 久久精品国产一区二区三区| 一区二区三区免费精品视频 | 亚洲国产一区二区a毛片| 精品国产亚洲一区二区三区| 无码人妻一区二区三区免费n鬼沢| 免费视频精品一区二区三区| 久久精品国产亚洲一区二区| 人妻久久久一区二区三区| ...91久久精品一区二区三区 | 亚洲乱码一区av春药高潮| 人妻激情偷乱视频一区二区三区| 亚洲一区二区三区四区视频| 国产成人综合一区精品| 在线免费一区二区| 亚洲av午夜精品一区二区三区| 国模吧无码一区二区三区|