一個專案的前端佈局給我的思考

源自世界發表於2017-04-26

內容包括: HTML(講述你不知道的absolute和float關係)和javascript(自己寫的一段原生js實現雙擊切換效果)

最近在一個專案中發現一個自己一直忽視的問題 position 和 float 的混用問題,position定位給我們前端開發中頁面的佈局帶來了很多的好處,但如果頁面使用過多的position定位,你將會發現,頁面的佈局超出了你的控制,就算是最終經過各種修改嘗試,頁面達到了你的設計效果,但是回過頭來你再審視你的程式碼你會不禁感慨‘我擦,這是一坨什麼!’。

所以,需要加深基礎的學習,從而簡化佈局工作量,用最少的程式碼來實現我們所需要的佈局效果,通過這次的實踐我發現了自己前端開發中存在知識缺陷問題,所以寫了一篇文章和大家相互學習。

要實現的頁面佈局效果是下面這個樣子的,它由三部分組成選單按鈕,導航欄,側邊欄,看到這個樣子同學會不以為然,‘不就是這麼常見的佈局嗎?貌似也不會有什麼技術含量呀!你不會是在逗我吧’

點選檢視效果示例

一個專案的前端佈局給我的思考
最終效果圖

這時我想說,‘no!no no no!各位看官莫急,且聽在下慢慢道來’,我們如果在每個模組加上不同顏色的邊框你就會發現不同之處,下面圖片中的一些模組的名稱定義,需要記一下喲,這會更方便你閱讀全文:
點選檢視效果示例
一個專案的前端佈局給我的思考
各個模組加邊框後的顯示效果

1.使用圖文混合的佈局解決導航欄的佈局

<a class="l-link" href="javascript:;">
    <div class="l-float">
        ![](./svg/menu.svg)
    </div>
</a>

<ul class="l-list">
    <li class="l-list-item">首頁</li>
    <li class="l-list-item">分類一</li>
    <li class="l-list-item">分類二</li>
    <li class="l-list-item">分類三</li>
</ul>複製程式碼

我們常見的形式為:

 ![](default.jpg)
 <p>這是一個圖文混合佈局</p>複製程式碼

是有一個行內元素和一個塊狀元素組成,或者是有inline, inline-block, block轉換的行內元素或者塊狀元素。

2.使用position定位中的 absolute或者fixed的特性,由於fixed是absolute的擴充套件,只是定義改變了定位出現的形式,所以fixed繼承了absolute的破壞性和包裹性兩個特性。對於這兩個特性不瞭解的同學可以百度相關方面的文章。

一個專案的前端佈局給我的思考
百度搜尋好文章

在上述程式碼結構上加上l-container容器,使用position:fixed,使用fixed的包裹性
效果圖如下:

一個專案的前端佈局給我的思考
包裹特性使用後效果圖

使用過圖文混合效果的同學應該知道,右邊導航欄的高度隨著左邊的高度變化而變化,所以解決l-list 的高度不是內容的高度的方法即是在l-list中加入overflow:hidden;即可做到如下圖的效果:

一個專案的前端佈局給我的思考
position-float-5.png

  程式碼結構如下:

 <div class="l-container">
      <a class="l-link" href="javascript:;">
         ……
      </a>

      <ul class="l-list">
        ……
      </ul>
</div>複製程式碼

3.側邊欄和選單按鈕的佈局(講述你不知道的absolute和float關係)

它們是兄弟關係,都能使元素脫離文件流(慕課網知識充電),但是還有一層關係你要知道?集中注意力往下看你喲!
如何使導航欄中的選單按鈕達到更好的使用者觸發使用效果?
所以設計成了如最終效果圖顯示的佈局,
a,增大按鈕的可觸發範圍使之與側邊欄的寬度等距;
b,使選單按鈕一部分遮擋側邊欄的一部分割槽域,從而實現更好的切換效果

實現a設計簡單增加寬高樣式,如果不能設定將元素轉化為行內塊狀元素。
側邊欄的實現不用說就是position:fixed;或者position:absolute;
實現b就要稍微動一下心思。
通常,當我們寫完程式碼後測試發現,效果並不是我們想的樣子,我們發現實際顯示效果是側邊欄的一部分遮擋住了選單按鈕,‘我擦,這個難不住機智的我們’,使用z-index:99999999;但是我們重新整理頁面後發現不是這個樣子的,這是為什麼呢?

我們都知道float ,和 absolute 都能使被修飾的模組脫離文件流,但是脫離文件流後兩者的層級關係如何,這個問題有的人想過,可能大部分人都沒有想過,這個我也看過很多文章發現基本沒有人說的明白。但是這並不妨礙我發表一下個人的觀點:
雖然float和absolute都能使元素脫離文件流,但是absolute脫離文件流後就不影響原來所處容器內的元素佈局,但是float卻不是,舉一個最常見的例子就是清除浮動,所以,雖然說float,absolute都是脫硫文件流,但嚴格地講float應該稱之為半脫離文件流。因此在層級關係上來說absolute的層級更高。 從我們寫的這個例子來講l-container positon:fixed;
l-menu float:left;樣式後,l-container包裹(理解包裹特性)l-menu也可以知道absolute的層級高於float的層級。
github下載程式碼如果喜歡記得新增個星星^-^
雖然有些同學不知道這是為什麼,但是不妨礙我們解決問題,那就是將l-container和 l-postion這兩個同根模組都設定position:absolute或者position:fixed;樣式,對就是這個樣子的,我們開發的過程中與到類似的問題,我們也是採用了‘同一性’的原則,就像我們在解決不同瀏覽器相容性問題時採用的normal.css一樣,將屬性同一。

這部分的程式碼結構是:

 <div class="l-container">
      <a class="l-link" href="javascript:;">
         ……  // 選單按鈕
      </a>

      <ul class="l-list">
        ……  // 導航
      </ul>
</div>

<div class="l-position">
 …… // 側邊欄
</div>複製程式碼

附上:js側邊欄實現的js原生程式碼:

var flag = true; // 顯隱識別符號
var obj = document.getElementsByClassName('l-link')[0]; 
var lPos = document.getElementsByClassName('l-position')[0];

obj.onclick = function(){
    if(flag){
        // 新增選擇器l-active
        objClass = lPos.getAttribute('class') || '';
        lPos.setAttribute('class', objClass + ' l-active');
        return flag = false;
    } else {
        // 去除選擇器l-active
        objClass = lPos.getAttribute('class');
        objArr = objClass.split(/\s+/);
        if(objArr && objClass !== null){
            for(var i=0, len=objArr.length; i<len; i++ ) {
                if(objArr[i] === 'l-active'){
                    objArr.splice(i, 1);
                }
            }
            var objClass2 = objArr.join(' ').replace(/^\s|\s$/g, '');
            lPos.setAttribute('class', objClass2) ;
            return flag = true;
        }
    }
}複製程式碼

github下載地址:

本文相關檔案為position-float.html和position-float.html

其他檔案有時間不妨也點一下,相信或多或少會對你有一定的幫助!感謝支援!

相關文章