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

hahadelphi發表於2021-09-09

前言

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

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

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

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

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

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

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

彈出層層次關係

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

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

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

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

彈出層的問題

這裡先稍微借鑑一點這裡的彈出層做說明:

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+)一般類彈出層,根據彈出先後順序計算

圖片描述

結語

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

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/2471/viewspace-2811655/,如需轉載,請註明出處,否則將追究法律責任。

相關文章