在前面介紹了整體前端工程的一些規范化原則及做法,這樣基本上可以保證前端工程的內部不會過度混亂。
本節我們將深入每個網頁本身,處理適配性和兼容性問題。適配性指的是頁面對瀏覽器大小的適配,兼容性指的是網頁對于不同瀏覽器的兼容。
同樣介紹了網頁適配性和兼容性的必要性,下面介紹具體的解決方法。
注意:在項目前期需要規劃好網頁運行的瀏覽器(包括PC端和手機端),這樣可以在開發階段和單元測試時盡早發現適配性和兼容性問題,在項目開發過程中消化這些瑣碎的工作。
適配性指的是網頁對瀏覽器大小的適配,雖然很多時候大型網站都會獨立出PC網頁和手機網頁兩部分(也有可能根據不同展示端獨立出更多的部分),但是不可避免的是,同類型設備的分辨率會有差別,PC瀏覽器窗口大小也可以隨意調整,這些因素都會影響網頁的顯示。一個適配性不好的網頁,會經常出現網頁元素錯位等不良現象,極度影響用戶體驗。
為了解決適配性問題,響應式布局的概念被提出。響應式布局就是一個網頁能夠兼容多個終端,如圖3.35所示。
圖3.35 響應式布局的網頁
響應式布局有很多具體的實現方法,如Flex彈性布局、Grid網格布局、Bootstrap的柵格系統等。但是,很多時候這些響應式布局方法并不能很好地解決網頁適配性的問題。問題的關鍵并不是這些響應式布局的方法不夠好,而是使用者本身對網頁的布局沒有一個正確的認知,如圖3.36所示。
圖3.36 錯誤的網頁布局認知
在圖3.36中確實是一個完整的骨架圖,也表現出了所有網頁元素的布局,但是這樣的布局認知卻是無法做好網頁布局的。因為這種布局認知太過于具體,所以在實現響應式布局的時候就需要顧及太多的細節,導致無法很好地實現響應式布局。就好像“把大象放進冰箱一共需要幾步”這個問題一樣,我們不應該一開始就著眼于全部細節(思考怎么鋸開大象),而是應該從宏觀上審視這個問題,把大象抽象成一個物品,那么我們就很容易得出“打開冰箱—把大象裝進去—關冰箱門”這樣的答案,至于怎么把大象塞進去,那是“把大象裝進去”這個步驟中的細節。同理,正確的網頁布局認知應該是有層次的,這里把網頁布局分成兩層,即整體層和模塊層,如圖3.37所示。
圖3.37 把網頁布局分成兩層
整體層是忽略頁面的細節,在整體上把網頁分成合理的幾個模塊(區域);模塊層是各模塊分區的具體細節。
說明:對布局分層只是對布局的思考方式,在畫網頁骨架圖時,還是類似于圖3.36那樣比較好一些。
響應式布局中提到整體層是忽略頁面的細節,在整體上考慮頁面各分區的布局。這里一個網頁需要適配不同的終端,包括PC瀏覽器和手機瀏覽器。
雖然設備分辨率是各式各樣的,但是可以按照瀏覽器橫向分辨率將其劃分為小屏手機(<576px)、手機(≥576px)、平板(≥768px)、桌面顯示器(≥992px)和大桌面顯示器(≥1200px)。很多時候,對于整體布局而言,小屏手機和手機的整體布局是一致的,平板、桌面顯示器和大桌面顯示器的整體布局是一致的,所以我們大部分時候只需要關注768px這個分水嶺就可以了。
注意:這里說的瀏覽器分辨率和設備分辨率是有區別的。比如iPhone4的手機分辨率是960×640px,而iPhone 4上Safari瀏覽器的分辨率是320×480px。瀏覽器分辨率可以通過$(document).width()和$(document).height()獲取。
綜上,本節需要實現的整體布局如圖3.38所示,其中翻頁區域在手機瀏覽器中需要隱藏。
圖3.38 需要實現的整體布局
1.原生HTML開發
使用原生HTML開發當然是可以實現響應式布局的,CSS文件中可以設置樣式生效的瀏覽器的橫向分辨率,但是比較推薦的方法是根據瀏覽器的橫向分辨率設置兩個獨立的CSS文件,網頁會自動根據分辨率引用不同的CSS文件。HTML文件引用CSS文件的方式如代碼3.24所示,其中當瀏覽器的橫向分辨率小于768px時,styleA.css的樣式會生效;當瀏覽器的橫向分辨率大于等于768px時,styleB.css的樣式生效。
代碼3.24 HTML文件根據瀏覽器橫向分辨率引用CSS文件的方式
<link rel="stylesheet" href="styleA.css" media="screen and (max-width:
767px)">
<link rel="stylesheet" href="styleB.css" media="screen and (min-width:
768px)">
2.Bootstrap柵格系統
使用原生HTML開發能很好地應對網頁適配性,但是整個網站都通過這種方式實現適配性的話將會是一件麻煩的事情。因為一般手機頁面的整體布局就是豎排的,而且768px這個分水嶺是基本固定的,所以每個網頁都定制這樣的樣式會顯得特別煩瑣。
在3.3.3小節中提到的Bootstrap,其提供的柵格系統便是目前比較流行的響應式布局解決方案。
注意:在使用柵格系統之前,不要使用table元素作為布局的工具。這是因為基本上現有的響應式布局方法都不支持對table元素的調整。
下面對Bootstrap的柵格系統進行說明。在引用Boostrap必要的JavaScript文件和CSS文件后即可使用柵格系統,用柵格系統實現整體布局的例子如代碼3.25所示,其中,這里只設置了div的寬度,因為柵格系統本身不提供高度的設置,高度的設置在之后會講解。
代碼3.25 HTML文件根據瀏覽器的橫向分辨率引用CSS文件的方式
…
<head>
<!--設置此網頁信息后,網頁才會隨設備大小變化,否則,網頁的默認最小寬度為980px-->
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
<!--柵格系統的容器div,會鋪滿父區域的寬度-->
<div class="container-fluid">
<div class="row"> <!--柵格系統的行div -->
<div class="col-sm-12">搜索區域</div> <!--搜索區域div -->
<div class="col-sm-12">資源列表區域</div> <!--資源列表區域div -->
<!--翻頁區域div -->
<div class="col-sm-12 d-none d-sm-block">翻頁區域</div>
</div>
</div>
</body>
…
代碼3.25中,<div class="container-fluid"></div>和<divclass="row"></div>是使用柵格系統前必須引入的,這兩個div中的內容才是圖3.38顯示的內容。
Bootstrap的柵格系統把屏幕的寬度分成12等份,我們只需要選擇幾個等份的寬度即可。例子中col-sm-12指的是瀏覽器分辨率的寬度大于等于768px的情況下,鋪滿12份(100%寬度)。這里由于沒有設置瀏覽器的橫向分辨率小于768px的情況,所以在此情況下會默認鋪滿12份。“d-none d-sm-block”指的是瀏覽器的橫向分辨率小于768px的情況下,隱藏起來。需要注意的是,dnone d-sm-block是Bootstrap 4的做法,在Bootstrap 3版本下有其他設置方式。Bootstrap柵格系統更詳細的說明見官方文檔https://v4.bootcss.com/docs/layout/overview/。
這里出現了一個問題,柵格系統的12等分看起來很難精確地還原UI設計,除非UI設計中的整體布局也是恰巧按照12等分設計的。其實網頁無論怎么實現,都很難百分百還原UI設計。這是因為UI設計是基于固定分辨率制作的圖片,而網頁是不可能只在一個分辨率下顯示的,所以UI設計中很多經過精心計算的尺寸都很難在網頁中百分百實現。對于網頁美觀性而言,更多的是著重于細節(如字體大小、組件美化等),而整體布局,只需要大概趨近比例即可。
如果整體布局的比例需要很嚴格地按照UI設計的比例實現,那么Bootstrap的柵格系統不太合適,需要使用其他布局方式進行實現,如Grid網格布局等。
3.整體布局的模塊高度
在很多響應式布局方法中,尤其是Bootstrap的柵格系統,高度的描述是經常被忽略的,這是因為響應式布局要求一個網頁適配多個終端,高度默認是作為寬度變化的補償。也就是說,如果某塊網頁內容在一些分辨率中是一行顯示,而寬度變窄了之后只能兩行顯示的話,高度需要自動變化,只有這樣才能把內容顯示完全。因此,響應式布局一般不需要設置固定的高度,讓高度自動變化即可。
但是,一些網頁的設計(尤其是PC網頁)是一屏設計(沒有滾動),本小節需要實現的整體布局也是一屏設計,這樣的話,高度的描述就不能被忽視。
那么整體布局需要如何應對這種一屏設計呢?一般的做法是固定一些模塊的高度,其他模塊再鋪滿這個頁面。具體代碼如下所示,其中CSS設置如代碼3.26所示,HTML如代碼3.27所示。
代碼3.26 CSS設置
/* 設置網頁的大小鋪滿整個窗口 */
.Page_body{
position: absolute;
height:100%;
width: 100%;
}
/* 設置柵格系統的container和row的高度為父區域的100% */
.Body_Container{
height:100%;
margin:0px;
}
/* 設置搜索區域的高度為50px */
.Body_Search {
height:50px;
background:gray;
}
/* 設置資源列表區域的高度鋪滿網頁剩下的高度 */
.Body_Resource {
height:calc(100% - 50px - 50px - 20px);
margin-bottom: 10px;
margin-top: 10px;
background:gray;
}
@media (max-width: 767px) { /* 設置當翻頁區隱藏時,資源列表區域的高度 */
.Body_Resource {
height:calc(100% - 50px - 10px);
margin-bottom: 0px;
}
}
/* 設置翻頁區域的高度為50px */
.Body_Page {
height:50px;
background:gray;
}
代碼3.27 HTML部分
<head>
<!--設置此網頁信息后,網頁才會隨設備大小變化,否則,網頁的默認最小寬度為980px-->
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
<div class="Page_body"> <!-- 增加網頁根div,設置網頁鋪滿整個窗口 -->
<!-- 增加高度的樣式設置 -->
<div class="container-fluid Body_Container">
<div class="row Body_Container"> <!-- 增加高度的樣式設置 -->
<div class="col-sm-12 Body_Search">搜索區域</div>
<div class="col-sm-12 Body_Resource">資源列表區域</div>
<div class="col-sm-12 d-none d-sm-block Body_Page">翻頁區域</div>
</div>
</div>
</div>
</body>
在代碼3.26中,固定了搜索區域和翻頁區域的高度,由資源區域鋪滿整個頁面。設置資源列表區域的高度時用到了CSS的calc()函數,這個函數可以動態計算長度值,使用這個函數后,即使隨意縮放瀏覽器窗口,資源區域也會鋪滿頁面。以上代碼的顯示效果如圖3.39所示。
圖3.39 整體布局效果
提醒:例子中設置高度時使用的單位為px,而響應式布局一般提倡使用rem這個單位。rem是相對單位,是相對瀏覽器默認字號的比例,而瀏覽器默認字號會隨著設備不同而有所區別,所以rem這個單位就可以間接地實現適應屏幕的效果。不過,在實際開發中,由于設置了<metaname="viewport"content="width=device-width,initial-scale=1">這個屬性,使用px或rem單位的效果都差不多,而UI設計提供的單位一般都是px,使用rem單位的話還需要換算,所以個人還是喜歡用px作為單位。
模塊層是各模塊分區的具體細節,模塊層布局一般是組織頁面控件等元素。對于這些控件,需要根據模塊的div進行相對布局,不能全部以左上角為參考點。
模塊布局由于是比較精細的布局,場景也是多種多樣的,而且相對于整體布局,模塊區域的布局一般不受屏幕大小的影響,除非手機網頁和普通網頁有不同的布局設計,所以不太推薦使用Bootstrap的柵格系統這些比較固定的布局模式,推薦的方法是根據不同的場景做不同的定制。使用HTML原生開發比較好一些,以搜索區域的模塊布局為例,布局的思路和整體布局中設置高度的思路類似,固定一部分元素的尺寸,其他元素填充剩余的空白,其中CSS代碼如代碼3.28所示,HTML代碼如代碼3.29所示,效果如圖3.40所示。
代碼3.28 CSS設置
/* 設置搜索區域樣式 */
.Body_Search {
height:50px;
background:gray;
padding:6px 10px;
padding-right:10px;
}
/* 設置搜索區域的輸入框樣式 */
.Body_Search_Input{
width: calc(100% - 100px - 10px);
margin-right: 10px;
float: left;
}
/* 設置搜索區域的搜索按鈕輸入框 */
.Body_Search_Button{
width: 100px;
}
代碼3.29 HTML代碼
<div class="col-sm-12 Body_Search">
<input class="form-control Body_Search_Input"><button class="btn btn-primary Body_Search_Button">搜索</button>
</div>
圖3.40 搜索區域的布局效果
當然,對于比較復雜的結構(例如圖3.37中的資源列表區域),可以把它再細化分層,使用一些響應式布局工具可能會方便一些,但是這些布局工具一定是項目初期已經確定好的JavaScript庫、組件工具箱或框架中的內容。
無論前端開發經驗多么豐富,我們都不可能在寫前端代碼的時候就能預見所有適配性的問題。所以需要在開發過程中,經常性地做適配性測試。
這里的適配性測試當然不是拿著幾個顯示器和手機來回嘗試,而是使用瀏覽器自帶的模擬器來做測試。以Chrome瀏覽器為例,打開調試工具(按F12鍵)后,單擊toggle device toolbar按鈕開啟調試模式,如圖3.41所示。開啟調試模式后效果如圖3.42所示。
圖3.41 Chrome瀏覽器的調試工具
注意:在軟件測試階段還是推薦用真機測試為主,這里提供的模擬測試方法只作為補充使用,這樣能很大程度上避免模擬器與真機的差異。
圖3.42 開啟調試模式的效果
兼容性指的是網頁對不同瀏覽器的兼容。在3.2.2小節中已經提到了一般需要兼容的瀏覽器,本節介紹一些具體的解決思路。
由于瀏覽器內核(渲染引擎)和瀏覽器API有所區別,所以相同的網頁運行在不同的瀏覽器上是有差別的。這些瀏覽器的差異,大部分已經被JavaScript庫、組件工具箱及前端框架解決掉了。因此選用這些工具后,也意味著解決了大部分的瀏覽器兼容性問題,但是仍有一部分需要我們去解決。
造成瀏覽器發生兼容性問題主要有三部分原因,第一部分是瀏覽器內核(渲染引擎)的差異,其會讓網頁的顯示效果有所差異。第二部分是JavaScript解析器的差異,雖然絕大部分瀏覽器的JavaScript解析器對JavaScript的語法支持沒有區別(都支持ECMAScript5標準),但是在一些瀏覽器API的調用上是有區別的。第三部分是一些瀏覽器特有的限定,如微信中內嵌的瀏覽器,它劫持了播放器,不允許以一般的方式修改播放器樣式,只能通過特定的方式修改。下面將對這三個部分展開介紹。
說明:最初的瀏覽器內核指的是渲染引擎和JavaScript解析器,后來JavaScript解析器被獨立,因此現在都比較習慣直接稱渲染引擎為瀏覽器內核。
1.瀏覽器內核(渲染引擎)
首先介紹比較流行的瀏覽器及其瀏覽器內核,如表3.1所示。其中國內的瀏覽器都傾向使用雙內核,這大概是歷史遺留問題,一些國內的交易網站的運行環境還必須是IE內核(如使用網銀盾等產品的網站)。
表3.1 比較流行的瀏覽器及其內核
由于瀏覽器內核(渲染引擎)影響的是網頁顯示的效果,所以解決不同瀏覽器內核造成的影響一般在HTML和CSS這兩部分上。HTML部分的問題相對少一些,除了IE 6~IE 10對一些HTML5的標簽不識別外,基本上沒有兼容性的問題。
CSS部分需要解決的問題多一些,雖然現在絕大多數瀏覽器都支持CSS3標準(除了IE),大部分的CSS屬性設置上都是相同的,但是某些內核的私有屬性是需要區分瀏覽器內核的。以設置圓角屬性為例,如代碼3.30所示。
注意:現在在CSS中設置圓角屬性基本上不需要區分內核,使用border-radius即可。這里只是為了講解方便,以一個比較常用且過去需要適配不同內核的屬性為例。
代碼3.30 CSS設置圓角屬性
.class{
-webkit-border-radius: 8px; /*Blink、WebKit內核設置圓角*/
-moz-border-radius: 8px; /*Gecko內核設置圓角*/
border-radius: 8px; /*其他內核設置圓角*/
}
由于瀏覽器內核造成的顯示效果差異,可以在開發過程中根據具體問題尋找對應的方法,這里不展開介紹。
2.JavaScript解析器
不同的JavaScript解析器帶來的差異一般體現在瀏覽器API調用上,如代碼3.31所示,其中調用瀏覽器全屏API需要根據瀏覽器進行區別。
代碼3.31 JavaScript調用瀏覽器全屏接口
if(elem.webkitRequestFullScreen){
elem.webkitRequestFullScreen(); //設置Chrome、Safari等瀏覽器全屏
}else if(elem.mozRequestFullScreen){
elem.mozRequestFullScreen(); //設置Firefox等瀏覽器全屏
}else if(elem.requestFullScreen){
elem.requestFullscreen(); //設置其他瀏覽器全屏
}else{
//IE9以下等瀏覽器不支持全屏功能
}
JavaScript解析器相對于瀏覽器內核帶來的兼容性問題相對較少,如果使用jQuery等JavaScript庫的話,基本上不會遇到需要兼容JavaScript解析器的問題,以上的例子也是筆者到目前為止發現的少數幾個需要解決的JavaScript解析器兼容性問題之一。
另外,由于JavaScript本身也在發展,新的語法只能在部分瀏覽器上被解析。例如,ECMAScript6標準的語法只有部分瀏覽器支持。不過,這類語法上的適配可以通過一些工具軟件進行轉換,例如,一些工具可以將ECMAScript6標準編寫的JavaScript代碼轉換成低版本的ECMAScript5代碼。
3.瀏覽器特有的限定
總有一些瀏覽器在某項功能上做了極其特別的處理,如在手機微信中嵌入的瀏覽器,它做了播放器劫持,瀏覽器會強行把播放器換成瀏覽器自己的播放器,開發者以普通的方式修改樣式是不會生效的,只能通過特定的方式修改。
當然,手機瀏覽器劫持播放器是普遍存在的現象,但是解決的方式卻不盡相同,有些甚至是不允許修改的。因此,對于瀏覽器特有的限定,只能根據不同的瀏覽器做不同的處理。對于這些特定的瀏覽器,可以通過JavaScript的navigator.userAgent變量獲取瀏覽器信息來判斷瀏覽器。
綜上,瀏覽器的兼容性問題很難預見,只能在測試中發現。瀏覽器的兼容性的測試沒有適配性測試方便,只能使用不同的瀏覽器做測試。不過,一般不需要將所有瀏覽器都測試一遍,以PC為例,使用Chrome、Safari和Firefox瀏覽器進行測試即可。其中Windows版的Safari瀏覽器是舊版,可能會造成一些測試上的困擾,不過Chrome瀏覽器的內核和Safari瀏覽器的內核比較相似,一般Chrome瀏覽器支持的內核在Safari瀏覽器里也會支持。
注意:解決瀏覽器兼容性問題除了顧及不同瀏覽器外,還要顧及相同瀏覽器的不同版本,如較新的Chrome瀏覽器提供了畫中畫功能,而舊版本的Chrome卻沒有這個功能。
面試官:你知道移動端適配嗎?
### 引言
在移動互聯網時代,Web前端工程師面臨的一大挑戰就是如何在各類尺寸各異的設備上實現優質的用戶體驗。移動端適配,正是解決這一問題的核心技術手段。本文將深入淺出地闡述移動端適配的相關概念、策略以及實戰技巧,讓你從容應對面試官的犀利提問。
### 一、移動端適配的基礎知識
**1.1 移動端設備屏幕多樣性**
當前市場上的移動設備種類繁多,屏幕尺寸、分辨率和像素密度差異巨大。為了確保網站在各種設備上都能正常顯示,移動端適配至關重要。
**1.2 視窗單位vw/vh與rem/em**
視窗單位vw/vh是相對于視口大小的百分比單位,可以幫助我們實現響應式布局:
```css
/* CSS 示例 */
.container {
width: 100vw;
height: 100vh;
}
```
相對單位rem/em則可以根據根元素字體大小自動縮放,便于整體布局的調控:
```css
html {
font-size: 62.5%; /* 將1rem設定為10px */
}
.container {
width: 30rem;
height: 20rem;
}
```
### 二、媒體查詢與響應式設計
**2.1 CSS媒體查詢**
媒體查詢是實現響應式設計的關鍵工具,通過檢測設備的特性來改變CSS樣式:
```css
@media screen and (max-width: 768px) {
.container {
width: 100%;
}
}
```
**2.2 Bootstrap網格系統**
Bootstrap等前端框架提供的響應式網格系統簡化了布局的適配工作,可根據屏幕大小自動分配列寬:
```html
<div class="container">
<div class="row">
<div class="col-sm-6 col-md-4">...</div>
<div class="col-sm-6 col-md-4">...</div>
<div class="col-sm-6 col-md-4">...</div>
</div>
</div>
```
### 三、移動端適配方案比較
**3.1 viewport元標簽**
通過設置viewport元標簽,可以控制頁面在移動設備上的初始縮放級別和布局視口大小:
```html
<meta name="viewport" content="width=device-width, initial-scale=1.0">
```
**3.2 自適應方案:Flexible布局(Flex布局)**
Flex布局可以方便地處理元素在父容器內的排列與對齊,極大簡化了復雜布局的適配過程:
```css
.container {
display: flex;
flex-wrap: wrap;
justify-content: space-around;
}
```
**3.3 移動設備像素比(devicePixelRatio)與高清屏適配**
針對高清屏設備,可以通過devicePixelRatio計算物理像素和CSS像素的比例,實現圖片等資源的高清顯示:
```javascript
let dpr = window.devicePixelRatio || 1;
let img = document.createElement('img');
img.src = `your-image-url?dpr=${dpr}`;
```
### 四、Vue.js移動端適配實戰
**4.1 Vue.js中的響應式布局**
在Vue項目中,可以結合Vue的計算屬性和偵聽器實現動態調整布局:
```javascript
export default {
data() {
return {
screenWidth: 0
};
},
computed: {
containerWidth() {
return `${this.screenWidth}px`;
}
},
mounted() {
window.addEventListener('resize', this.handleResize);
},
beforeDestroy() {
window.removeEventListener('resize', this.handleResize);
},
methods: {
handleResize() {
this.screenWidth = document.documentElement.clientWidth;
}
}
}
```
**4.2 Vue移動端UI組件庫的適配**
Vue生態中有許多成熟的移動端UI組件庫(如Vuetify、Element-UI Mobile等),它們內置了完善的移動端適配方案,開發者可以直接使用。
### 結語
移動端適配不僅是Web前端開發者必備的專業技能,也是衡量一個優秀前端工程師的標準之一。無論面試官拋出何種問題,只要你掌握了以上所述的適配策略與方法,就能胸有成竹地給出專業解答,順利通關面試環節。同時,持續關注行業新技術和最佳實踐,不斷提升自身在移動端適配領域的技術水平,才能在激烈的競爭中立于不敗之地。
KEditor 4.16.2 維護版本已發布。此版本是一個維護版本,更新內容包括修復安全問題、修復瀏覽器兼容性問題、升級與 React 的集成,以及修復其他重要問題。
修復安全問題
修復了剪貼板插件中的安全漏洞 (CVE-2021-32809),該漏洞會引起出現濫用粘貼功能(使用格式錯誤的 HTML )的情況,進而導致將任意的 HTML 注入編輯器。
此外,在 Widget 插件中發現的另一個漏洞 (CVE-2021-32808) 容易導致出現執行 JavaScript 代碼的情況,以及 Fake Objects 插件由于容易注入格式錯誤的 Fake Objects HTML (CVE-2021-37695),這也可能會導致執行 JavaScript 代碼。
修復瀏覽器兼容性問題
此版本針對多款瀏覽器引入了多項錯誤修正和增強功能,確保跨平臺兼容性,以提供最便捷的使用體驗。
升級與 React 的集成
與 React 的集成升級到了 2.0.0 版本,增加了對 React v17.x 的支持、對 React hooks 的支持,以及對 TypeScript 和類型的支持。詳情點此查看。
*請認真填寫需求信息,我們會在24小時內與您取得聯系。