【單頁應用】我們該如何處理框架彈出層層級關系?


前言

最近總結不多,一方面是之前的知識點多比較基礎,所以學習總結起來比較快

但是基礎知識只有那么一點,現在當然可以從新知識點着手拓寬視野(這個當然要繼續),但是基礎積累,再深入學習是成為優秀前端必不可少的階段

所以這塊地方還得死扛,所幸現在是個優秀的團隊,身邊高手前輩較多,有時候請教是很有方向的,這個很是幸運啊!

其次年后來到公司后,總有點浮浮沉沉的事情發生,而每年的3月又是各個公司“變化”的集中期,所以心境受到了一些影響,此點不可不慎啊!

搞技術的不可浮躁!如果心思過多的花在了“人事”上,那么就真有點背道而馳了,技術人員的核心競爭還是應當在技術上

當然,年后會為年前干的一些事情擦屁股,一般每個團隊年前都會有一些爛事沒有做完,剛好一些事情就落到了我的頭上,於是進入今日的主題

因為邊思考便行文,有問題請提出。

彈出層層次關系

以我現有視野來說,單頁應用應該是移動端的一個趨勢,很多公司或多或少的會要求HTML5的站點表現與APP趨於一致

而好的前端團隊的話就會要求HTML5不遜色與APP,當然這塊不是不可能發生(在一兩年后,應該逐漸明顯)

對於非單頁應用來說,彈出層的層次關系比較簡單,但是依舊會遇到一個彈出層彈出,另一個彈出層也需要彈出的場景

而上述比較“少見”的場景在單頁應用中就時常發生了,如果一開始沒有對自己框架的層級做設計的話,后面的發展會讓你覺得頭疼

彈出層的問題

這里先稍微借鑒一點這里的彈出層做說明:http://sentsin.com/jquery/layer/

PS:賢心彈出層是比較全面的,可以少寫很多代碼說明問題

小議層次關系

通過查看樣式我們發現其z-index為:

element.style {
background-color: rgb(255, 255, 255);
z-index: 19891015;
height: 132px;
}

那么,我這里就會產生一個疑問,如果再彈出一個alert框呢,當然這里會有以下場景:

① 由於蒙版的存在,只允許一個alert框彈出

② 框架本身做了處理,同一類型的alert框只能有一個

③ 框架對z-index做了處理,第二次彈出的層會遮住第一個(這里還會有其它情況我們稍后再說)

④ 未做特殊處理

現在,我們干一件很2B的事情,將蒙版去掉再點擊試試:

通過實驗發現,該作者的處理方式如下:

① 只允許一個alert彈出層的出現,與上面②方案類似

② 不同類型的彈出層需要同時出現時候,只會保留最新的一個

比如我們這里點擊詢問類的彈出層時候,再點擊信息框,於是詢問類的彈出層就被關閉了,再點擊確定就沒有了彈出層了

交叉層次處理

當遇到多個層次時候,也是需要處理的,繼續以這里的彈出層為例:我們連續彈出兩個層

 

后出來的層會在先出來的層次之前,意思是其z-index的值比較高,這個時候再加上一個loading框的話就比較齊全了

所以,這里我們可以得出一個結論:

作者是以先后出現順序設計層次結構的(未讀源碼,具體情況不明)

而,這個還只是第一種層次關系,比較細心的朋友會發現,左邊有一個fixed元素:

 

而fixed元素在單頁應用中多用作view的頭尾,那么alert類的彈出層與fixed頭尾又是什么關系呢??

fixed頭尾與彈出層

這里footer的樣式如下:

.fixnav {
position: fixed;
bottom: 0;
width: 100%; z-index: 9999;
transition: all .8s;
background: #206F96;
}

與上千萬的彈出層來說就比較渺小了

 

所以彈出層應該遮蓋頭尾(fixed),這個處理也是有道理的,但是這里也會有一個問題

頭部是否應該被遮蓋

對於單頁應用來說,頭部是否應該被遮蓋呢?

這個不同的人會有不同的想法:

① 不應該被遮蓋

如果一個loading框加載失敗,而代碼又未做處理的話,用戶除了刷新頁面或者退出程序別無他法

現在很多html5代碼會同時用於app中,而app的頭部是不可遮蓋的

② 應該被遮蓋

簡單而言,彈出層出現時不遮蓋頭部會引起很多BUG,對代碼的健壯性要求更高

比如,彈出層出現時候,點擊后退,如果業務代碼未對彈出層作出處理的話,這個彈出層不會消失

另外,如果view切換過程中會有動畫效果的話,view的會被設置為absolute,那么此時alert與頁面view會有層級關系

所以,保險的方案,應該是遮蓋頭部

出現次數問題

我們看到該作者的處理是相同的控件只能出現一次,這個處理方法對於單頁應用來說可能就有一定麻煩了:

① 我們當然可以在控制器中設置一些經常出現的彈出層插件:

alert類,彈出層類,讓他們只能出現一次,但是實際項目中,極有可能出現各個view對彈出層的需求不一樣的需求

這個時候我們的彈出層應該被控制么?

② 彈出層會自帶蒙版(mask),這個蒙版又該出現幾次呢

③ 全屏覆蓋層(廣告類,或者其他)又該處於什么層次呢???

讓我們帶着這些問題一一學習今日的知識

全局唯一的彈出層

由設計的角度來說,無論是出現蒙版還是其它因素,我們對一些彈出層是只要求單獨存在的,比如,我們不會希望同時存在兩個alert

所以,我們先整理哪些彈出層只會出現一次:

① alert 類警告層

② confirm 類確認層

③ toast類消息層

④ loading類加載層

⑤ 其它類似彈出層

以上彈出層事實上全局只應該有一個,dom一旦存在就不會銷毀,但是這里也會有其它問題,比如我們這個confirm吧

統一控件不同行為

我們現在在demo01時候希望點擊確定時候彈出個確定的提示,而提示相關有所不同的話......

 

 

就需要每次show的時候傳遞參數復寫上一次的事件等相關數據:

showConfirm: function (message, title, okFn, cancelFn, okTxt, cancelTxt) {
  //如果傳入的是對象的話,直接用作初始化
  if (typeof message == 'object' && message.message) {
    this.confirm.setViewData(message);
  } else {
    this.confirm.setViewData({
      message: message,
      title: title,
      buttons: [
      { text: (cancelTxt || '取消'), click: function () {
        if (typeof cancelFn == 'function') { cancelFn(); }
        this.hide();
      }, type: Alert.STYLE_CANCEL
      },
      {
        text: (okTxt || '確定'),
        click: function () {
          if (typeof okFn == 'function') { okFn(); }
          this.hide();
        },
        type: Alert.STYLE_CONFIRM
      }
    ]
    });
  }
  this.confirm.show();
},

這塊的結論是:

同一控件需要在show時候動態改變事件句柄相關參數,以達到dom結構重復利用的目的

這個操作是很簡單的,有問題的是我們的mask控件,如果我們的mask控件具有點擊mask關閉alert控件功能的話,情況就有所不同了

需要幾個mask

我們的框架到底需要幾個mask,這個問題其實比較關鍵

全局只有一個mask,dom代碼清晰,這個想法非常合理,但不易操作

怎么說呢,如果存在兩個彈出層同時存在的情況,A彈出層出來后,B彈出層再出來,這個時候A的蒙版應該比A高比B低

這個時候關掉B,mask又應該比A低,於是我們需要去動態調整蒙版的zindex

以上場景已經比較煩了,如果我們有點擊蒙版關閉插件的需求的話,我們點擊蒙版時候該關閉B還是該關閉A呢???

情況又變得復雜起來,實現起來容易照成BUG,所以簡單的方案還是,每個彈出層為其配置一個mask,是否具有點擊關閉特性由插件決定

比如loading框就不具有關閉特性,所以結論是:

為每一個彈出層配置單獨mask是比較簡單的處理方案

阻止彈出層層次

彈出層出現次數確定后,第二個問題就是其出現時候的層級關系,我們這里采用:

按彈出層出現先后順序確定其層級

比如我們幾個層同時出現時候,我們就按照其出現順序定義誰在錢誰在后,在后面的會被蒙版遮住(這里可能會導致蒙版愈來愈黑)

 

那么這個時候層次關系應該怎么確定呢,或者說,我怎么知道我每次取得的z-index都會最大,這個其實就和我們前面的uuid是一個道理了

base.getBiggerzIndex = (function () {
  var diviso =  1000;
  return function () {
    return ++diviso;
  };
})();

每次設置index時候都在這里來獲取z-index即可

header與footer

header與footer根據我們前面的想法,應該是被遮住的,所以,我們直接將其z-index設置為500即可

但是這個時候依舊會有一些特殊的情況,比如warning404等情況

404提示

一般來說,404頁面應該比一般彈出層低,並且比header低,但是比footer高,為什么這么說呢

因為header可能全局只有一個,而footer來說屬於單個view,比如提交訂單的按鈕

這個時候404提示應該遮蓋所有的頁面,但是不能遮蓋頭部

頁面層級

頁面切換來說,會將view轉化為absolute,這個時候也會有一定層級的,這個時候又會有許多問題,比如footer欄為fixed元素,整個view切換時候他並不會跟着移動

所以,我們應該將footer欄做成組件,在切換時候將之隱藏

頁面切換時候的層級應該比header低,但是比一般的彈出層要高,所以我們最后可以形成以下規則

第一級別:(0)
文檔流元素

第二級別:(500)
footer類組件,需要在文檔流之上,依舊屬於view內部

第三級別:(1000)
404提示類,需要覆蓋view內的所有元素,但不能遮蓋頭部,屬於遮蓋view內部的彈出層

第四級別:(1500)
view切換時候的層級
此時view的層級會比404等層級高
框架切換時候需要對彈出層進行hide

第五級別:(2000)
header類,頭部

第六級別:(3000+)
一般類彈出層,根據彈出先后順序計算

結語

今天正好在整理框架的層級關系,將思考到的東西做了一定記錄,如果各位對此有研究請不吝賜教


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM