年做了大量的 HTML5 項目,遇到了很多坑。在這個過程中學(xué)到了一些之前不具備的知識,所以這篇文章就簡單分享一下這方面的話題。
傳統(tǒng)的MPA
首先,說一個比較古老的東西,叫做 MPA。
MPA 的全稱是 Multi-page Application,意思是整個應(yīng)用(站點)由多個完整的 html 構(gòu)成。用戶在頁面 1 點擊跳轉(zhuǎn),需要向服務(wù)端請求頁面 2,請求成功后渲染。而用戶返回時,相當(dāng)于是點擊了瀏覽器的返回,頁面退回到之前的歷史記錄,并重新加載出來。
在這樣的模式下,頁面間切換慢、不流暢的問題比較突出,尤其是在移動端。
同時,它還產(chǎn)生了幾個小問題:
SPA
隨著對移動端體驗需求的提高以及技術(shù)的進步,另一種模式 SPA(Single-page Application)逐漸成為主流。
SPA 簡單來說,就是原來在 MPA 中的多個 html,現(xiàn)在被放在了一個 html 中,并被分成若干個片段。跳轉(zhuǎn)、返回的本質(zhì)變成了分段的「隱藏」與「顯示」。跳轉(zhuǎn)不需要反復(fù)對服務(wù)端進行請求,從而使得頁面與頁面之間切換更加快速流暢。
在這樣的機制下,跳轉(zhuǎn)與返回完全由代碼控制,所以可以通過代碼定義頁面轉(zhuǎn)場的效果、返回。
在設(shè)計轉(zhuǎn)場動畫時,我們需要留意的是導(dǎo)航欄是 Native 的還是 HTML5 的。如果導(dǎo)航欄是 Native 的,那 HTML5 頁面不包括導(dǎo)航欄,它相當(dāng)于是網(wǎng)頁外的元素,不在轉(zhuǎn)場效果的設(shè)計范圍內(nèi)。
WebView
說 HTML5 的跳轉(zhuǎn),就不得不說 WebView。簡單來說,WebView 是在 App 中用于顯示 web 內(nèi)容的容器。上文提到的 MPA 和 SPA,都裝在了這個叫做 WebView 的容器中。
用戶點擊頁面中的元素進行跳轉(zhuǎn),除了前面的兩種方式外,還有第三種:新打開 WebView 的方式。在這樣的方式下,跳轉(zhuǎn)的本質(zhì)是 HTML5「告訴」Native,由 Native 執(zhí)行打開新 WebView,并在新 WebView 中加載頁面。
因為 Native 的機制,打開新 WebView 的同時,之前的 WebView 會被自然、完整地保留。所以這時,之前的幾個問題就變?yōu)椋?/p>
不過需要注意的地方是,打開新 WebView 是一個資源消耗比較大的操作。如果我們在設(shè)計一個流程時,需要比較多的連續(xù)使用這種方式,需要和研發(fā)同學(xué)進行充分的溝通。
比較特殊的Replace
前述的三種跳轉(zhuǎn),都會產(chǎn)生歷史記錄。MPA、SPA 的歷史記錄是在 HTML5 中產(chǎn)生,新開 WebView 中的記錄是在 Native 中產(chǎn)生。
在 MPA 或 SPA 中,如果跳轉(zhuǎn)時使用 Replace 方法,它會用新頁面替換之前的頁面,歷史記錄中沒有之前頁面的記錄。
這是一種特殊的跳轉(zhuǎn)方式,在設(shè)計一些不可逆的流程時可考慮使用。
多頁面回退
了解了上述的幾種機制后,我們來看一個小的應(yīng)用場景──多頁面回退。
我們在實際業(yè)務(wù)中,經(jīng)常會有這樣的需求。假設(shè)我們有 1、2、3 三個頁組成的一個流程,在頁面 3 上有個「完成」按鈕點擊回到頁面 1。在不同的交互模式下,實現(xiàn)這樣的跳轉(zhuǎn)有著不同的機制。
1. SPA模式下的正常跳轉(zhuǎn)
這種模式是 3 個頁面都在一個 WebView 中。點擊頁面 3 中的「完成」按鈕,回退 -2 ,即回退 2 步歷史記錄,到頁面 1。
2. 新打開WebView
打開新 WebView 又分三種方式。
如果我們把 3 個頁面,拆分到 2 個 WebView 中,如下圖,點擊完成按鈕,即關(guān)閉自身所在的 WebView。
同樣是打開新的 WebView,如果我們按如下圖的方法拆分會稍微復(fù)雜。這時點擊完成按鈕,首先關(guān)閉自身所在的 WebView,當(dāng)頁面 2「意識」到自己重新被展現(xiàn)時,自動退回 1 步到頁面 1。
每次打開新的 WebView,這時點擊完成,回退的本質(zhì)是 HTML5「告訴」Native 關(guān)閉多個 WebView。需要特別注意的是,HTML5 中實現(xiàn)這種方式不是天然具備的,它需要 Native 具有一次關(guān)閉多個 WebView 的能力。所以我們在設(shè)計方案時,需要了解清楚自家的 Native 是否有這樣的能力。
總結(jié)
以上,簡單說了幾種 HTML5 的跳轉(zhuǎn)方式。這些跳轉(zhuǎn)方式,沒有絕對的對與錯,我們在設(shè)計方案時,需要根據(jù)實際的業(yè)務(wù)需求與技術(shù)的限制,來整體考慮解決方案。
根據(jù)個人經(jīng)驗,也有幾點小帖士分享給大家:
航切換設(shè)計到CSS中標(biāo)簽屬性設(shè)置:隱藏、顯示
涉及html5異步傳輸?shù)奶匦?/p>
更需要知道js多標(biāo)簽時候元素選擇的寫法
再啰嗦一下:classLIst屬性返回元素的類名,可以用方法add()、remove()添加class屬性
setAttribute(name,value)設(shè)置新屬性及其值,或者修改已有屬性的值
正文
上導(dǎo)航切換的示意圖
js代碼:
<script>
window.onload = function () { //window.onload:就是等整個頁面內(nèi)容全部加載完畢
//填寫js邏輯
//獲取ul里li的個數(shù)
var tab_ui = document.getElementsByTagName("ul");
var tab_li= tab_ui[0].getElementsByTagName("li")
//獲取要顯示的div的個數(shù)
var content = document.getElementById("content");
var content_div = content.getElementsByTagName("div");
//給li添加鼠標(biāo)點擊事件
for(var i= 0;i<tab_li.length;i++){
tab_li[i].index = i; //異步傳輸,不設(shè)置的話,得到的都是i的最大值
tab_li[i].onclick = function () {
//清除之前的樣式
for(var j=0;j<tab_li.length;j++){
//沒有點擊事件,j=0,1,2
tab_li[j].classList.remove("active");
content_div[j].setAttribute("class","hidden");
}
//設(shè)置自己本身的樣式:添加class=active
this.setAttribute("class","active");
//content_div[i].classList.remove("hidden"); 無效,i=3導(dǎo)致
//將對應(yīng)的內(nèi)容顯示出來
content_div[this.index].classList.remove("hidden");
}
}
//給li添加鼠標(biāo)點擊事件
var tab_ui = document.getElementsByTagName("ul");
var tab_li1= tab_ui[1].getElementsByTagName("li")
//var tab_li1= document.getElementsById("li")
var content1 = document.getElementById("content1");
var content1_div = content1.getElementsByTagName("div");
for(var i= 0;i<tab_li1.length;i++){
tab_li1[i].index = i; //重點,為了讓i在循環(huán)體內(nèi)
tab_li1[i].onmouseover = function () {
//這里的i永遠(yuǎn)=3,如果不設(shè)置 tab_li[i].index = i
//清除之前的樣式
for(var j=0;j<tab_li1.length;j++){
//沒有點擊事件,j=0,1,2
tab_li1[j].classList.remove("active");
content1_div[j].setAttribute("class","hidden");
}
//設(shè)置自己本身的樣式:添加class=active
this.setAttribute("class","active");
//content_div[i].classList.remove("hidden"); 無效,i=3導(dǎo)致
//將對應(yīng)的內(nèi)容顯示出來
content1_div[this.index].classList.remove("hidden");
}
}
}
</script>
css代碼
<style>
.hidden{
display: none;
}
.tabdemo>.active{
background: red;
border-bottom-color:white ;
}
#wrap{
height: 58px;
background-color: #c7eafa;
}
.tabdemo {
width: 100%;
list-style: none;
margin: 0 auto;
background-color: blue;
}
.tabdemo1 {
width: auto;
list-style: none;
margin: 0 auto;
background-color: pink;
float:left;
}
li{
color: rgb(0, 0, 0);
display:inline-block;
}
ul.tabdemo1 li {
color: rgb(224, 9, 9);
display:block;
}
li:hover{
background-color: lavender;
}
a{
/*
一定注意要把a轉(zhuǎn)成行內(nèi)塊元素,
如果轉(zhuǎn)的是塊元素那么短豎線會掉下去,
因為塊級元素是獨占一行的
*/
display:inline-block;
padding: 0 20px;
line-height: 58px;
text-decoration: none;
color: black;
}
</style>
html代碼
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>多導(dǎo)航切換</title>
<script src="https://cdn.staticfile.org/jquery/1.10.2/jquery.min.js"></script>
</head>
//js代碼、css代碼放在這里
<body>
<div id="wrap">
<div>
<ul class="tabdemo">
<li class="active "><a class="ac" href="#">選擇1</a></li>
<li><a class="ac" href="#">選擇2</a></li>
<li><a class="ac" href="#">選擇3</a></li>
</ul>
</div>
<!--彈出內(nèi)容-->
<div id="content" style="padding:1px;border:dashed;">
<div id="first" class="show">
<a href="#">內(nèi)容一</a>
<a href="#">內(nèi)容一</a>
<a href="#">內(nèi)容一</a>
<a href="#">內(nèi)容一</a>
</div>
<div id="second" class="hidden">
<a href="#">內(nèi)容二</a>
<a href="#">內(nèi)容二</a>
<a href="#">內(nèi)容二</a>
<a href="#">內(nèi)容二</a>
</div>
<div id="third" class="hidden">
<a href="#">內(nèi)容三</a>
<a href="#">內(nèi)容三</a>
<a href="#">內(nèi)容三</a>
<a href="#">內(nèi)容三</a>
</div>
</div>
<!--彈出內(nèi)容-->
<div>
<ul class="tabdemo1">
<li class="active "><a class="ac" href="#">選擇1</a></li>
<li><a class="ac" href="#">選擇2</a></li>
<li><a class="ac" href="#">選擇3</a></li>
</ul>
</div>
<div id="content1" style="padding:1px;border:dashed;">
<div id="first" class="show">
<a href="#">內(nèi)容一</a>
<a href="#">內(nèi)容一</a>
<a href="#">內(nèi)容一</a>
<a href="#">內(nèi)容一</a>
</div>
<div id="second" class="hidden">
<a href="#">內(nèi)容二</a>
<a href="#">內(nèi)容二</a>
<a href="#">內(nèi)容二</a>
<a href="#">內(nèi)容二</a>
</div>
<div id="third" class="hidden">
<a href="#">內(nèi)容三</a>
<a href="#">內(nèi)容三</a>
<a href="#">內(nèi)容三</a>
<a href="#">內(nèi)容三</a>
</div>
</div>
</div>
</body>
</html>
HTML5的優(yōu)良特性很快被各種類型的網(wǎng)站利用,比如文件拖拽到網(wǎng)頁上傳功能,多數(shù)即使用HTML5提供的新屬性就可以完成,來實現(xiàn)素材的免插件拖放。因此,HTML5技術(shù)實際上在國內(nèi)已經(jīng)獲得了較廣泛的應(yīng)用與支持。從硬件角度來看,國內(nèi)手機和平板兩種移動設(shè)備應(yīng)用最廣,PC端次之,緊接著是電視和游戲設(shè)備。從軟件角度來看,桌面瀏覽器對HTML5的支持高于移動瀏覽器,最高可達95%;而從整體上而言,移動瀏覽器對HTML5的支持卻優(yōu)于桌面瀏覽器。根據(jù)百度流量研究院統(tǒng)計,2016年國內(nèi)桌面瀏覽器市場份額最大的是Chrome,約占39.4%;IE次之,約占29.24%。其中,占比高達17%的IE 8.0對HTML5并不友好。然而,微軟已宣布停止對IE 6-10的技術(shù)支持,并打算放棄IE瀏覽器及Windows 10以下系統(tǒng)。因此,低版本IE份額正呈快速下降趨勢,2016年降到2%以下。
1.4.4 HTML5平臺的興起
2014年,在微信平臺的幫助下,HTML5社交小游戲獲得爆炸式傳播,同期為HTML5平臺以提供制作工具服務(wù)進入市場的起點。到了2015年,越來越多公司在HTML5品牌推廣上進行布局。在商業(yè)需求的驅(qū)動下,HTML5頁面設(shè)計的目的性更強,獲得最好傳播效果的基本是經(jīng)過一定時間策劃,在團隊操作下有針對性地進行投放的企業(yè)案例。相對應(yīng)地,原有HTML5平臺也進行了大面積升級。從平臺性質(zhì)而言,HTML5平臺可分為輕營銷模板類、功能引擎類和基礎(chǔ)工具類三種:
(1)輕營銷模板類:提供類似PPT頁面切換的HTML5制作工具,通常面向個人用戶,部分為企業(yè)用戶。該類平臺的數(shù)量較大,只適用于輕度營銷,所能提供的頁面動態(tài)效果局限于翻頁。如圖1所示:
圖1 易企秀桌面工具編輯界面和作品
*請認(rèn)真填寫需求信息,我們會在24小時內(nèi)與您取得聯(lián)系。