2019年3月8日 星期五

jQuery UI 學習筆記 (一) : 主題布景 (Themes)

今天複習 EasyUI 時想到 jQuery UI 也很久沒碰了, 感覺都很生疏. 特別是 jQuery UI 還被我拿來設計公司的專案, 每天工作都會看到這個介面, 但怎麼用卻真的忘記了. 為了快速恢復功力, 我看了之前寫的這篇 :

jQuery UI 執行環境配置

搞清楚其架構後, 去 jQuery UI 官網下載了最新版來測試, 作為將其整合到 Django 專案的準備動作. 我下載的是 jQuery UI 1.21 版 (搭配 jQuery 1.7+) 及主題布景 themes :




解壓縮 jquery-ui-themes-1.12.1.zip 後複製 index.htm, jquery-ui.js 以及 /external/jquery/jquery.js 到測試目錄下. 另外解壓縮 jquery-ui-themes-1.12.1.zip 後, 將整個 themes 目錄 (裡面有 25 個主題布景) 也複製到測試目錄下, 檔案架構如下 :




然後修改 Demo 網頁 index.htm, 將其更名為 jqueryui_themes_test_1.htm, 修改 CSS Link 的 href 如下 :

<script src="jquery.js"></script>
<script src="jquery-ui.js"></script>
<link id="theme" href="themes/hot-sneaks/jquery-ui.min.css" rel="stylesheet">

這個名為 hot-sneaks 的主題布景是 jQuery UI 的 25 種布景中我最喜愛的一個, 也是我在公司專案中的預設布景. 只要更改 CSS Link href 中的資料夾路徑即可更改布景, 例如 themes/base/jquery-ui.min.css 即名為 base 之布景.

可不可以讓使用者選擇自己喜歡的布景呢, 可以的, 這可以在網頁上加個下拉式選單列舉 25 種布景, 使用者可從裡面隨意挑選一個, 選定後布景馬上會改變. 這個選單如下所示 :

<select id="themes" onchange="javascript:change_theme();">
    <option value="base">base</option>
    <option value="black-tie">black-tie</option>
    <option value="blitzer">blitzer</option>
    <option value="cupertino">cupertino</option>
    <option value="dark-hive">dark-hive</option>
    <option value="dot-luv">dot-luv</option>
    <option value="eggplant">eggplant</option>
    <option value="excite-bike">excite-bike</option>
    <option value="flick">flick</option>
    <option value="hot-sneaks" selected>hot-sneaks</option>
    <option value="humanity">humanity</option>
    <option value="le-frog">le-frog</option>
    <option value="mint-choc">mint-choc</option>
    <option value="overcast">overcast</option>
    <option value="pepper-grinder">pepper-grinder</option>
    <option value="redmond">redmond</option>
    <option value="smoothness">smoothness</option>
    <option value="south-street">south-street</option>
    <option value="start">start</option>
    <option value="sunny">sunny</option>
    <option value="swanky-purse">swanky-purse</option>
    <option value="trontastic">trontastic</option>
    <option value="ui-darkness">ui-darkness</option>
    <option value="ui-lightness">ui-lightness</option>
    <option value="vader">vader</option>
  </select>

注意, 此選單被指定了一個 id=themes, 而且加上一個呼叫 change_theme() 函數的 onchange 的事件, 函數內容如下 :

function change_theme() {
  var theme=$("#themes").val();
  var href="themes/" + theme + "/jquery-ui.min.css";
  $("#theme").attr("href", href);
  }

此處利用 val() 取得選單被選到之選項值, 然後用 attr() 設定 id 為 theme 的 link 樣式元素之 href 屬性, 從而立刻改變整個網頁之布景. 參考 :

change the href of a css link via jquery

結果如下 :

測試 1 : 使用者更換 jQuery UI 主題布景 (1) [看原始碼]




不過這個 HTML 原味的選單與 jQuery UI 的選單放在一起似乎不搭調, 如何將其改為 jQuery UI 風味的下拉式選的呢? 這必須呼叫 selectmenu() 來使其變身 :

$("#themes").selectmenu(); 

不過這樣一來就不能用上面那個 change_theme() 來處理 onchange() 事件了, 因為 jQuery UI 有自己的事件處理方式, 因此下拉式選單改為如下沒有 onchange() 的 :

<select id="themes">
    <option value="base">base</option>
    <option value="black-tie">black-tie</option>
    <option value="blitzer">blitzer</option>
    <option value="cupertino">cupertino</option>
    <option value="dark-hive">dark-hive</option>
    <option value="dot-luv">dot-luv</option>
    <option value="eggplant">eggplant</option>
    <option value="excite-bike">excite-bike</option>
    <option value="flick">flick</option>
    <option value="hot-sneaks">hot-sneaks</option>
    <option value="humanity">humanity</option>
    <option value="le-frog">le-frog</option>
    <option value="mint-choc">mint-choc</option>
    <option value="overcast">overcast</option>
    <option value="pepper-grinder">pepper-grinder</option>
    <option value="redmond">redmond</option>
    <option value="smoothness">smoothness</option>
    <option value="south-street">south-street</option>
    <option value="start">start</option>
    <option value="sunny">sunny</option>
    <option value="swanky-purse">swanky-purse</option>
    <option value="trontastic">trontastic</option>
    <option value="ui-darkness">ui-darkness</option>
    <option value="ui-lightness">ui-lightness</option>
    <option value="vader">vader</option>
  </select>

jQuery UI 的 onchange 事件名為 selectmenuchange, 需呼叫 on() 函數來為此 selectmenu 加上事件監聽器, 參考:

How to handle jQuery UI Selectmenu change event

$("#themes").selectmenu();
$('#themes').on('selectmenuchange', function() {
  var theme=$(this).val();
  var href="themes/" + theme + "/jquery-ui.min.css";
  $("#theme").attr("href", href);
  });

注意, 這裡必須用 $(this) 才能呼叫 val(), 因為 this 乃是指 DOM 物件, 必須套上 $() 變成 jQuery 物件後才能呼叫 val(). 參考 :

jQuery 中的 this 與 $(this) 用法差異

執行效果如下 :

測試 2 : 使用者更換 jQuery UI 主題布景 (2) [看原始碼]





以前我是在後端 PHP 輸出主題布景 Link 之 href, 但這樣每次改布景網頁要重載, 感覺不太好, 其實應該像這樣用前端控制才對.

但是上面測試 2 網頁中的每一個元件與字型似乎太大了, 要怎麼設定才能看起來不會那麼大呢? 這必須在 Style 元素中設定 body 的樣式, 將 font-size 調小到 10px 左右即可, 參考 :

Changing jQuery UI Button size? :

在 head 標籤的 style 內加上如下樣式 :

body {
    font-family: Arial, Helvetica, sans-serif;
    font-size:10px;
    }

結果如下 :

測試 3 : 使用者更換 jQuery UI 主題布景 (3) [看原始碼]




All right, 這樣就不會那麼大了. 但我佈署在公司運營中的專案不打算調小, 因為同事們都有老花眼了.

還有一個問題, HTML 網頁中的 CSS Link 中的設定值是網頁初載入時的預設布景, 下拉式選單的預設值應該也要設定成那個選項才會一致, 但下拉式選單被我們變身為 selectmenu 元件後要怎麼設定其預設值呢? 很簡單, 也是使用 val(), 此函數雙重用途, 有傳入參數是 setter 函數, 沒傳入參數則為 getter(). 假如 CSS Link 預設使用 hot-sneaks 布景 :

<link id="theme" href="themes\hot-sneaks\jquery-ui.min.css" rel="stylesheet">

則設定 selectmenu 元件預設值方法如下 :

$("#themes").selectmenu();
$("#themes").val("hot-sneaks");
$("#themes").selectmenu("refresh");

注意, 最後一定要呼叫 refresh 函數才會生效. 參考 :

Set a jQuery UI selectmenu to a specific option by javascript

結果如下 :

測試 4 : 使用者更換 jQuery UI 主題布景 (4) [看原始碼]




以上都是使用自備的 jQuery 與 jQuery UI 函式庫, 其實也可以使用 CDN 資源, 好處是節省空間, 下面是將測試 4 改為微軟 CDN 供檔的做法, 此 CDN 有提供 themes 主題布景, 只要將 CSS 與 Javascript 改為如下即可 :

  <link id="theme" href="https://ajax.aspnetcdn.com/ajax/jquery.ui/1.12.1/themes/hot-sneaks/jquery-ui.css" rel="stylesheet">
  <script type="text/javascript" src="https://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.12.4.min.js"></script>
  <script type="text/javascript" src="https://ajax.aspnetcdn.com/ajax/jquery.ui/1.12.1/jquery-ui.min.js"></script>

程式控制 CSS 之 theme 路徑部分也要隨同修改 :

$("#themes").selectmenu();
$("#themes").val("hot-sneaks");
$("#themes").selectmenu("refresh");
$('#themes').on('selectmenuchange', function() {
  var theme=$(this).val();
  var href="https://ajax.aspnetcdn.com/ajax/jquery.ui/1.12.1/themes/" +  
           theme + "/jquery-ui.css";
  $("#theme").attr("href", href);
  });

參考 :

https://docs.microsoft.com/en-us/aspnet/ajax/cdn/jquery-ui/
# https://docs.microsoft.com/en-us/aspnet/ajax/cdn/overview

執行結果如下 :

測試 5 : 使用者更換 jQuery UI 主題布景 (5) [看原始碼]