2019年3月28日 星期四

jQuery UI 學習筆記 (十一) : 選單 (Menu)

今天繼續來測試 jQuery UI 的選單 (menu). Menu 是個分門別類管理資料的好用工具, 可以大大節省版面空間並使資料井井有條, 例如用來導覽公司網頁中的產品型錄等等, 記得以前都要用一堆 CSS 與 Javascript 才能做出這種功能, 現在用 jQuery UI 很簡單就能實現了.

Menu API 與教學文件參考 :

https://jqueryui.com/menu/
http://api.jqueryui.com/menu/

本篇測試參考了如下書籍 :
  1. jQuery UI 使用者介面設計 (歐萊里, Studio Tib. 譯)
  2. jQuery UI 與 Plugin 開發實戰 (悅知文化, 吳哲穎譯)
  3. jQuery 全能權威指南 (上奇, 張亞飛)
  4. Pro jQuery 2.0 second eddition (Apress, Freeman Adam)
jQuery UI 的選單主要使用 HTML 的清單結構 (即 ul 與 li 元素) 組成, ul 是選單的容器, li 則是選項的容器. 每一個選項都必須用一個 div 元素包起來 (這是必要的, 因渲染後產生的部分樣式是要套用在此 div 上), 例如 :

  <ul id="menu-1">
    <li>
      <div>submenu-1</div>
      <ul>
        <li>
          <div>item-1-1</div>
        </li>
        <li>
          <div>item-1-2</div>
        </li>
      </ul>
    </li>
    <li>
      <div>submenu-2</div>
      <ul>
        <li>
          <div>item-2-1</div>
        </li>
        <li>
          <div>item-2-2</div>
        </li>
      </ul>
    </li>
    <li>
      <div>item-1</div>
    </li>
    <li>
      <div>item-2</div>
    </li>
  </ul>

其中主選單 menu-1 含有兩個子選單 submenu-1 與 submenu-2, 以及兩個選項 item-1 與 item-2, 階層可以一直延伸下去, 只要在 li 內再放 ul 即可. 例如 :


測試 1 : 書訊導覽 [看原始碼]

注意, 此例在 style 元素中添加了 class 為 ui-menu 的樣式, 用來將選單及其子選單都限制為同一寬度.

CSS 部分 :

<style>
.ui-menu {width: 100px;}
</style>

HTML 部分 :

  <ul id="books">
    <li>
      <div>網路書店</div>
      <ul>
        <li>
          <div>博客來</div>
        </li>
        <li>
          <div>金石堂</div>
        </li>
        <li>
          <div>誠品</div>
        </li>
      </ul>
    </li>
    <li>
      <div>圖書館</div>
      <ul>
        <li>
          <div>高科大</div>
        </li>
        <li>
          <div>高雄市圖</div>
        </li>
      </ul> 
    </li>
  </ul>

jQuery 部分 :

$("#books").menu();




此例第一層兩個選項均有子選單, 滑鼠移至項目上時會展開子選單. 在 Chrome 按 F12 進入開發者模式, 切到 Element 頁籤可檢視經 jQuery UI 渲染後的 HTML 如下 :




可見選單的每一個 ul 元素都被添加了許多樣式 class, 其中第一個樣式是 ui-menu, 此 class 可用來限定選單與所有子選單之寬度.

如果把上面測試 1 的 ui-menu 的寬度設定拿掉, 則主選單會占滿父元素的寬度, 如果是在網頁的最上層, 則會占滿全螢幕, 可能會破壞整個版面, 例如 :


測試 1-1 : 書訊導覽 (沒有設定 ui-menu 樣式之寬度) [看原始碼]

其次, 每個選項都必須用 div 包起來, 否則主題布景無法套用, 例如將上面測試 1 中各選項的 div 都拿掉的話, padding 與主題布景等樣式就不見了 :


測試 1-2 : 書訊導覽 (沒有 div) [看原始碼]






可見製作 jQuery UI 選單有兩個必要條件 :
  1. 一定要為選單設定寬度樣式.
  2. 每個選項都必須用 div 包起來.
注意, ui-menu 的樣式會套用到主選單與所有子選單, 如果不想一體套用, 也可以在代表選單的 ul 元素中用 in-line 樣式進行寬度設定 :

<ul id="menu-1" style="width:100px;">

好處是可以根據各選單中最長選項的長度來調整寬度, 而非套用同樣的寬度. 例如 :


測試 2 : 為各別選單設置寬度 [看原始碼]

HTML 部分 :

  <ul id="books" style="width: 100px;">
    <li>
      <div>網路書店</div>
      <ul style="width: 80px;">
        <li>
          <div>博客來</div>
        </li>
        <li>
          <div>金石堂</div>
        </li>
        <li>
          <div>誠品</div>
        </li>
      </ul>
    </li>
    <li>
      <div>圖書館</div>
      <ul style="width: 100px;">
        <li>
          <div>高科大</div>
        </li>
        <li>
          <div>高雄市圖</div>
        </li>
      </ul> 
    </li>
  </ul>

jQuery 部分 :

$("#books").menu();




此例去除了測試 1 中 style 元素內的 ui-menu 等級寬度設定, 轉而為代表選單的 ul 元素各別設定 style 屬性, 可見子選單 "網路書店" 因為項目之最長字數為 3, 寬度被設成較短的 80px.

如果要為選項加上超連結, 只要用 a 元素包裹選項 Label 即可, 例如 :


測試 3 : 為各選項加上超連結 [看原始碼]

HTML 部分 :

  <ul id="books">
    <li>
      <div>
        <a>網路書店</a>
      </div>
      <ul>
        <li>
          <div>
            <a href="https://www.books.com.tw" target="_blank">博客來</a>
          </div>
        </li>
        <li>
          <div>
            <a href="https://www.kingstone.com.tw" target="_blank">金石堂</a>
          </div>
        </li>
        <li>
          <div>
            <a href="http://www.eslite.com.tw" target="_blank">誠品</a>
          </div>
        </li>
      </ul>
    </li>
    <li>
      <div>
        <a>圖書館</a>
      </div>
      <ul>
        <li>
          <div>
            <a href="https://nkust.primo.exlibrisgroup.com" target="_blank">高科大</a>
          </div>
        </li>
        <li>
          <div>
            <a href="https://www.ksml.edu.tw" target="_blank">高雄市圖</a>
          </div>
        </li>
      </ul> 
    </li>
  </ul>

jQuery 部分 :

$("#books").menu();




此例中每一個被 a 元素包起來的 li 選項都有一個底線表示此為超連結, 似乎有點破壞視覺純淨感, 這可以為 a 元素加上 text-decoration:none 樣式設定解決, 例如 :



CSS 樣式 :

    .ui-menu {width: 100px;}
    a {text-decoration:none;}

HTML 與測試 3 相同. 

以上是選單的基本用法. 下面則針對 menu 常用的選項, 方法, 與事件進行測試. 常用屬性如下表 :

 常用 option 說明
 disabled 不可用狀態 (true/false, 預設 false)
 icons 指定選單上的按鈕 (字串, 預設 "ui-icon-carat-1-e")

常用方法如下表 :

 常用 method 說明
 option 取得或設定選項之值
 disable 禁能 (等於 disabled 屬性=True)
 enable 致能 (等於 disabled 屬性=False)
 refresh 重新渲染元件
 collapseAll 關閉所有開啟之子選單

常用事件如下表 :

 常用 event 說明
 create 建立物件時觸發
 blur 項目失去焦點時觸發
 select 項目被選擇時觸發
 focus 項目取得焦點時觸發

下列範例綜合測試了 icons, disabled 等屬性, 以及 option, disable, enable, open, close 等方法 :



HTML 部分 :

  <ul id="books" style="width: 100px;">
    <li>
      <div>網路書店</div>
      <ul style="width: 80px;">
        <li>
          <div>博客來</div>
        </li>
        <li>
          <div>金石堂</div>
        </li>
        <li>
          <div>誠品</div>
        </li>
      </ul>
    </li>
    <li>
      <div>圖書館</div>
      <ul style="width: 100px;">
        <li>
          <div>高科大</div>
        </li>
        <li>
          <div>高雄市圖</div>
        </li>
      </ul> 
    </li>
  </ul><br>
  <button id="enable-disable">Enable</button>
  <button id="collapseAll">collapseAll</button><br><br>
  <textarea id="output"></textarea>

jQuery 部分 :

      var config={
        disabled: true,
        icons: {submenu: "ui-icon-circle-triangle-e"},
        create: function(e, ui) {
          var html="觸發 create 事件 : " +  $(this).val() + "\n" +
                   $("#output").html();
          $("#output").html(html);
          },
        blur: function(e, ui) {
          var html="觸發 blur 事件 : " +  $(this).val() + "\n" +
                   $("#output").html();
          $("#output").html(html);
          },
        focus: function(e, ui) {
          var html="觸發 focus 事件 : " +  $(this).val() + "\n" +
                   $("#output").html();
          $("#output").html(html);
          },
        select: function(e, ui) {
          var html="觸發 select 事件 : " +  $(this).val() + "\n" +
                   $("#output").html();
          $("#output").html(html);
          }
        };
      $("#books").menu(config);
      $("#enable-disable").button();
      $("#enable-disable").on("click", function() {
        var str=$("#enable-disable").html();
        if (str=="Enable") {
          $("#books").menu("option", "disabled", false);
          //$("#books").menu("enable");  //另一個做法
          $("#enable-disable").html("Disable");
          }
        else {
          $("#books").menu("disable");
          $("#enable-disable").html("Enable");
          }
        });
      $("#collapseAll").button();
      $("#collapseAll").on("click", function() {
        $("#books").menu("collapseAll");
        });





此例在 menu 物件建立時將表單設為不可用, 並用 icons 選項設定新的子選單圖像, 然後監視 create, focus, select, blur 等事件.

沒有留言 :