2019年11月28日 星期四

Bootstrap 4 學習筆記 (八) : 導覽頁籤

導覽是網頁設計很重要的功能, 通常用在首頁中引導使用者快速找到目標內容. Bootstrap 的導覽元件可以設計出頁籤面板 (tabbed panel), 或結合下拉式選單以簡化網頁結構.

本系列之前的測試文章參考 :


Bootstrap 4 學習筆記 (一) : 環境配置
Bootstrap 4 學習筆記 (二) : 網格與容器
Bootstrap 4 學習筆記 (三) : 表格
Bootstrap 4 學習筆記 (四) : 圖示與按鈕
Bootstrap 4 學習筆記 (五) : 文字與圖片效果
Bootstrap 4 學習筆記 (六) : 表單
Bootstrap 4 學習筆記 (七) : 按鈕選單


Bootstrap 教學文件參考 :

第 10 堂課 - 初探 bootstrap 網頁製作
Bootstrap 初學介紹 #靜態篇


一. 導覽頁籤相關之樣式類別 : 

Bootstrap 的導覽元件使用 ul-ui 清單項目為基本架構, 每一個 li 元素代表一個導覽項目, 並提供如下表中之樣式類別來設定導覽元件 :


 導覽元件樣式類別 說明
 nav 導覽元件必要之基礎類別 (套用在 ul 元素)
 nav-tabs 頁嵌式導覽面板 (套用在 ul 元素)
 nav-pills 按鈕式導覽面板 (套用在 ul 元素)
 nav-stacked 堆疊式導覽面板 (套用在 ul 元素)
 nav-justified 在大於 768px 螢幕上讓導覽項目以平均寬度排列 (套用在 ul 元素)
 data-toggle 套用在 ui 元素, 指定切換導覽頁籤時觸發之事件, 頁籤要設為 tab
 data-url 套用在 ui 元素, 指定以 Ajax 方式載入導覽頁籤之 URL 
 tab-content 套用於頁籤內容版面外層 div 元素 (整個頁籤面板)
 tab-pane 套用於頁籤內容版面內層 div 元素 (個別頁籤)
 active 啟用導覽項目 (套用在 ui 元素) 或頁籤面板 (套用在 div 元素)
 disabled 停用導覽項目 (套用在 ul 元素) 或頁籤面板 (套用在 div 元素)


其中 nav 類別為基礎類別, 必須率先套用.


二. 頁籤內容來自網頁本身 : 

導覽元件分為兩個部分 :
  • 表頭 (header) :
    類似活頁簿的標籤, 由 ul 與 ui 元素搭配 nav 與 nav- 樣式類別構成.
  • 內容 (content) :
    由兩層 div 元素搭配 tab-content 與 tab-pane 樣式類別構成. 
如果頁籤內容來自網頁本身, 則頁籤內容直接放在雙層 div 的內層; 如果頁籤內容來自 Ajax 取得, 則內層 div 不需要內容.


範例 1 : 導覽頁籤 nav-tab 樣式 [看原始碼]


<!DOCTYPE html>
<html>
  <head>
    <title></title>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width,initial-scale=1">
    <link rel="stylesheet" href="https://unpkg.com/bootstrap@3.3.7/dist/css/bootstrap.min.css">
    <link rel="stylesheet" href="https://unpkg.com/bootstrap@3.3.7/dist/css/bootstrap-theme.min.css">
    <script src="https://unpkg.com/jquery@3.4.1/dist/jquery.min.js"></script>
    <script src="https://unpkg.com/bootstrap@3.3.7/dist/js/bootstrap.min.js"></script>
  </head>
  <body>
    <div class="container">
      <ul class="nav nav-tabs">
        <li><a href="#home" data-toggle="tab">首頁</a></li>
        <li><a href="#board" data-toggle="tab">留言板</a></li>
        <li><a href="#download" data-toggle="tab">下載區</a></li>
        <li><a href="#config" data-toggle="tab">設定</a></li>
      </ul>
      <div class="tab-content" style="padding:10px;">
        <div class="tab-pane active" id="home">
          <p>這是首頁</p>
        </div>
        <div class="tab-pane" id="board">
          <p>這是留言板</p>
        </div>
        <div class="tab-pane" id="download">
          <p>這是下載區</p>
        </div>
        <div class="tab-pane" id="config">
          <p>這是設定</p>
        </div>
      </div>
    </div>
    <script>
      $(document).ready(function(){
        });
    </script>
  </body>
</html>


此例中 ul 與 li 結構組成導覽頁籤, 兩層 div 結構組成各頁籤內容. ul 須先套用 nav 再套用 nav-tab 樣式, li 的 href 須設定為指向頁籤內容的內層 div 元素之 id. 頁籤內容之外層 div 須套用 tab-content 樣式, 而內層 div 則是套用 tab-pane 樣式並設定 id 屬性, 以便與導覽頁籤的 href 相連結. 每個 li 元素都必須有 data-toggle 屬性並設定其值為 "tab", 瀏覽結果如下 :



若改用 nav-pills, 則頁籤會改用按鈕樣式, 例如 :


範例 2 : 導覽按鈕 nav-pills 樣式 [看原始碼]


<!DOCTYPE html>
<html>
  <head>
    <title></title>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width,initial-scale=1">
    <link rel="stylesheet" href="https://unpkg.com/bootstrap@3.3.7/dist/css/bootstrap.min.css">
    <link rel="stylesheet" href="https://unpkg.com/bootstrap@3.3.7/dist/css/bootstrap-theme.min.css">
    <script src="https://unpkg.com/jquery@3.4.1/dist/jquery.min.js"></script>
    <script src="https://unpkg.com/bootstrap@3.3.7/dist/js/bootstrap.min.js"></script>
  </head>
  <body>
    <div class="container">
      <ul class="nav nav-pills">
        <li><a href="#home" data-toggle="tab">首頁</a></li>
        <li><a href="#board" data-toggle="tab">留言板</a></li>
        <li><a href="#download" data-toggle="tab">下載區</a></li>
        <li><a href="#config" data-toggle="tab">設定</a></li>
      </ul>
      <div class="tab-content" style="padding:10px;">
        <div class="tab-pane active" id="home">
          <p>這是首頁</p>
        </div>
        <div class="tab-pane" id="board">
          <p>這是留言板</p>
        </div>
        <div class="tab-pane" id="download">
          <p>這是下載區</p>
        </div>
        <div class="tab-pane" id="config">
          <p>這是設定</p>
        </div>
      </div>
    </div>
    <script>
      $(document).ready(function(){
        });
    </script>
  </body>
</html>


瀏覽結果如下 :



不論是 nav-tabs 還是 nac-pills, 其頁籤或按鈕都是向左靠, 若再套用 nav-justified 的話, 頁籤或按鈕將不會向左靠, 而是平均分享頁面寬度, 例如 :


範例 3 : 導覽按鈕 nav-justified 樣式 [看原始碼]


<!DOCTYPE html>
<html>
  <head>
    <title></title>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width,initial-scale=1">
    <link rel="stylesheet" href="https://unpkg.com/bootstrap@3.3.7/dist/css/bootstrap.min.css">
    <link rel="stylesheet" href="https://unpkg.com/bootstrap@3.3.7/dist/css/bootstrap-theme.min.css">
    <script src="https://unpkg.com/jquery@3.4.1/dist/jquery.min.js"></script>
    <script src="https://unpkg.com/bootstrap@3.3.7/dist/js/bootstrap.min.js"></script>
  </head>
  <body>
    <div class="container">
      <ul class="nav nav-pills nav-justified">
        <li><a href="#home" data-toggle="tab">首頁</a></li>
        <li><a href="#board" data-toggle="tab">留言板</a></li>
        <li><a href="#download" data-toggle="tab">下載區</a></li>
        <li><a href="#config" data-toggle="tab">設定</a></li>
      </ul>
      <div class="tab-content" style="padding:10px;">
        <div class="tab-pane active" id="home">
          <p>這是首頁</p>
        </div>
        <div class="tab-pane" id="board">
          <p>這是留言板</p>
        </div>
        <div class="tab-pane" id="download">
          <p>這是下載區</p>
        </div>
        <div class="tab-pane" id="config">
          <p>這是設定</p>
        </div>
      </div>
    </div>
    <script>
      $(document).ready(function(){
        });
    </script>
  </body>
</html>


瀏覽結果如下 :





上面範例即使瀏覽器寬度縮減, nav-tabs 與 nav-pills 的頁籤都不會往下摺疊, 但套用 nav-justified 則會折疊. 如果要固定上下折疊效果可明確套用 nav-stacked 樣式, 如下範例所示 :


範例 4 : 導覽按鈕 nav-stacked 樣式 [看原始碼]


<!DOCTYPE html>
<html>
  <head>
    <title></title>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width,initial-scale=1">
    <link rel="stylesheet" href="https://unpkg.com/bootstrap@3.3.7/dist/css/bootstrap.min.css">
    <link rel="stylesheet" href="https://unpkg.com/bootstrap@3.3.7/dist/css/bootstrap-theme.min.css">
    <script src="https://unpkg.com/jquery@3.4.1/dist/jquery.min.js"></script>
    <script src="https://unpkg.com/bootstrap@3.3.7/dist/js/bootstrap.min.js"></script>
  </head>
  <body>
    <div class="container">
      <ul class="nav nav-pills nav-stacked">
        <li><a href="#home" data-toggle="tab">首頁</a></li>
        <li><a href="#board" data-toggle="tab">留言板</a></li>
        <li><a href="#download" data-toggle="tab">下載區</a></li>
        <li><a href="#config" data-toggle="tab">設定</a></li>
      </ul>
      <div class="tab-content" style="padding:10px;">
        <div class="tab-pane active" id="home">
          <p>這是首頁</p>
        </div>
        <div class="tab-pane" id="board">
          <p>這是留言板</p>
        </div>
        <div class="tab-pane" id="download">
          <p>這是下載區</p>
        </div>
        <div class="tab-pane" id="config">
          <p>這是設定</p>
        </div>
      </div>
    </div>
    <script>
      $(document).ready(function(){
        });
    </script>
  </body>
</html>


此例選定 nav-pills 樣式後再套用 nav-stacked 樣式, 使得導覽按鈕不論瀏覽器寬度為何君固定以上下堆疊方式呈現, 瀏覽結果如下 :




三. 頁籤內容來自遠端 (Ajax) : 

以上範例之導覽頁籤內容均來自網頁本身, Bootstrap 可否利用 Ajax 從遠端 (即伺服器) 取得呢? 可以的, 但是須搭配 Javascript 程式控制. 使用 Ajax 方式取得頁籤內容之導覽網頁時, li 元素中的超連結 a 元素須用 data-url 屬性指定遠端網頁來源之 URL, 參考 :

https://www.bootply.com/0uzrsETEjS

例如 :


範例 5 : 用 Ajax 取得遠端導覽頁籤內容 (1) [看原始碼]


<!DOCTYPE html>
<html>
  <head>
    <title></title>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width,initial-scale=1">
    <link rel="stylesheet" href="https://unpkg.com/bootstrap@3.3.7/dist/css/bootstrap.min.css">
    <link rel="stylesheet" href="https://unpkg.com/bootstrap@3.3.7/dist/css/bootstrap-theme.min.css">
    <script src="https://unpkg.com/jquery@3.4.1/dist/jquery.min.js"></script>
    <script src="https://unpkg.com/bootstrap@3.3.7/dist/js/bootstrap.min.js"></script>
  </head>
  <body>
    <div class="container">
      <ul class="nav nav-tabs" id="tabs">
        <li class="active"><a href="#home" data-url="home.htm">首頁</a></li>
        <li><a href="#board" data-url="board.php">留言板</a></li>
        <li><a href="#download" data-url="download.php">下載區</a></li>
        <li><a href="#config" data-url="config.php">設定</a></li>
      </ul>
      <div class="tab-content" style="padding:10px;">
        <div class="tab-pane active" id="home"></div>
        <div class="tab-pane" id="board"></div>
        <div class="tab-pane" id="download"></div>
        <div class="tab-pane" id="config"></div>
      </div>
    </div>
    <script>
      $(document).ready(function(){
        $('#tabs a').click(function (e) {  //當按下 id=tabs 中的超連結時
          e.preventDefault();                   //阻止事件向上提升 (處理一次)    
          var url=$(this).attr("data-url");  //取得 data-url 屬性值
          var href=this.hash;                     //取得 href 值
          var pane=$(this);                       //轉成 DOM 物件
          $(href).load(url,function(result){   //載入頁嵌內容
            pane.tab('show');                           //將此頁籤設為顯示 (active)
            });
          });
        $('#home').load($('.active a').attr("data-url"), function(result){
          $('.active a').tab('show');   //載入首頁時
          });
        });
    </script>
  </body>
</html>


此例導覽頁籤中的 a 元素都改用 data-url 來指定遠端網頁檔案, 故必須先準備 home.htm, board.php, download.php, 以及 config.php 這四個遠端檔案, 其內容很簡單, 就 "這是下載區" 之類的. 例如 board.php 內容為 :


<?php
echo "<p>這是留言板</p>"
?>

而 home.htm 內容為 :


<p>這是首頁</p>


瀏覽結果如下 :



注意, 此例必須上傳伺服器才有效, 直接在本機檔案系統開啟無法載入頁籤內容, 會出現如下錯誤 :




上面的範例也可以改成透過 GET 傳參數, 例如 :


範例 6 : 用 Ajax 取得遠端導覽頁籤內容 (2) [看原始碼]


<!DOCTYPE html>
<html>
  <head>
    <title></title>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width,initial-scale=1">
    <link rel="stylesheet" href="https://unpkg.com/bootstrap@3.3.7/dist/css/bootstrap.min.css">
    <link rel="stylesheet" href="https://unpkg.com/bootstrap@3.3.7/dist/css/bootstrap-theme.min.css">
    <script src="https://unpkg.com/jquery@3.4.1/dist/jquery.min.js"></script>
    <script src="https://unpkg.com/bootstrap@3.3.7/dist/js/bootstrap.min.js"></script>
  </head>
  <body>
    <div class="container">
      <ul class="nav nav-pills" id="tabs">
        <li class="active"><a href="#home" data-url="tabs.php?text=這是首頁">首頁</a></li>
        <li><a href="#board" data-url="tabs.php?text=這是留言板">留言板</a></li>
        <li><a href="#download" data-url="tabs.php?text=這是下載區">下載區</a></li>
        <li><a href="#config" data-url="tabs.php?text=這是設定">設定</a></li>
      </ul>
      <div class="tab-content" style="padding:10px;">
        <div class="tab-pane active" id="home"></div>
        <div class="tab-pane" id="board"></div>
        <div class="tab-pane" id="download"></div>
        <div class="tab-pane" id="config"></div>
      </div>
    </div>
    <script>
      $(document).ready(function(){
        $('#tabs a').click(function (e) {
          e.preventDefault();       
          var url=$(this).attr("data-url");
          var href=this.hash;
          var pane=$(this);
          $(href).load(url,function(result){
            pane.tab('show');
            });
          });
        $('#home').load($('.active a').attr("data-url"), function(result){
          $('.active a').tab('show');
          });
        });
    </script>
  </body>
</html>


此例頁籤超連結的 URL 都改成 tabs.php?text=xxx 了, 亦即將欲顯示的文字透過 text 參數傳遞給 tabs.php, 因此只要準備一個 tabs.php 即可, 內容如下 :


<p><?php echo $_GET['text'] ?></p>


同樣地, 此範例不能在本機測試, 須上傳伺服器.

導覽頁籤的每一個頁籤都可以改成按鈕選單, 只要將 li 頁籤套上 dropdown 樣式類別 (取代原案鈕選單中的最外層 div 元素), button 按鈕改成頁籤的超連結按鈕, 套用 dropdown-toggle 並加上 data-toggle="dropdown" 屬性即可, 如下列範例所示 :


範例 7 : 導覽頁籤內容為按鈕選單 [看原始碼]


<!DOCTYPE html>
<html>
  <head>
    <title></title>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width,initial-scale=1">
    <link rel="stylesheet" href="https://unpkg.com/bootstrap@3.3.7/dist/css/bootstrap.min.css">
    <link rel="stylesheet" href="https://unpkg.com/bootstrap@3.3.7/dist/css/bootstrap-theme.min.css">
    <script src="https://unpkg.com/jquery@3.4.1/dist/jquery.min.js"></script>
    <script src="https://unpkg.com/bootstrap@3.3.7/dist/js/bootstrap.min.js"></script>
  </head>
  <body>
    <div class="container">
      <ul class="nav nav-tabs">
        <li><a href="#home" data-toggle="tab">首頁</a></li>
        <li><a href="#board" data-toggle="tab">留言板</a></li>
        <li class="dropdown">
          <a href="#" class="dropdown-toggle" data-toggle="dropdown">
            <label>圖書館</label>
            <span class="caret"></span>
          </a>
          <ul class="dropdown-menu">
            <li>
              <a href="http://webpac.ksml.edu.tw" target="_blank">市立圖書館</a>
            </li>
            <li>
              <a href="https://nkust.primo.exlibrisgroup.com/" target="_blank">高科大圖書館</a>
            </li>
          </ul>
        </li>
        <li class="dropdown">
          <a href="#" class="dropdown-toggle" data-toggle="dropdown">
            <label>網路書店</label>
            <span class="caret"></span>
          </a>
          <ul class="dropdown-menu">
            <li class="dropdown-header">國外</li>
            <li><a href="https://www.amazon.com/" target="_blank">亞馬遜書店</a></li>
            <li><a href="https://www.barnesandnoble.com/" target="_blank">Barnes & Noble</a></li>
            <li class="divider"></li>
            <li class="dropdown-header">國內</li>
            <li><a href="http://www.book.com.tw/" target="_blank">博客來書店</a></li>
            <li><a href="http://www.eslite.com/" target="_blank">誠品書店</a></li>
            <li><a href="http://www.kingstone.com.tw/" target="_blank">金石堂書店</a></li>
          </ul>
        </li>
      </ul>
      <div class="tab-content" style="padding:10px;">
        <div class="tab-pane active" id="home">
          <p>這是首頁</p>
        </div>
        <div class="tab-pane" id="board">
          <p>這是留言板</p>
        </div>
      </div>
    </div>
    <script>
      $(document).ready(function(){
        });
    </script>
  </body>
</html>


此例只有前兩個頁籤有內容, 因此在雙層 div 頁籤內容部分只需要兩個內層 div 分別放置首頁與留言板之內容 (tab-pane); 而後兩個頁籤是按鈕選單, 以 a 元素超連結當按鈕用, 瀏覽結果如下 :





簡簡單單幾乎不須寫 Javascript 程式就能建立功能豐富的專業網頁, Bootstrap 實在太好用了!

參考 :

Creating Tabs with Bootstrap
如何利用Bootstrap的標籤(Tabs)和導覽列(Navigation Bar)
How to use AJAX loading with Bootstrap tabs?
# Bootstrap tabs with Ajax

沒有留言 :