左右からパネル
パネルです
横からスライドしてくるパネルですが、NuGetから落ちてくるjQuery Mobileの古いd.tsには含まれていません
仕方がないので自力で追加しますが、たいしたものではないのでcm.tsに含めてしまいます
/Src/cm.ts
/* * Panel */ interface PanelOptions { animate?: boolean; defaults?: boolean; disabled?: boolean; dismissible?: boolean; display?: string; initSelector?: string; position?: string; positionFixed?: boolean; swipeClose?: boolean; theme?: string; } interface PanelEvents { create?: JQueryMobileEvent; } interface JQueryMobile extends JQueryMobileOptions { panel: any; } interface JQuery { panel(): JQuery; panel(command: string): JQuery; panel(command: string, name: string): string; panel(command: string, name: string, value: string): JQuery; panel(options: PanelOptions): JQuery; panel(events: PanelEvents): JQuery; }
使いそうな分だけです
操作メソッドも追加します
/Src/cm.ts
/* * パネル */ namespace Panel { "use strict"; /* * クローズ */ export function close() { $(".ui-panel").panel("close"); } /* * オープン */ export function open(selector: string | JQuery): JQuery { let target = $(selector); switch (target.css("visibility")) { case "hidden": case "collapse": target.panel("open"); } return target; } /* * 表示設定 */ export function setVisible(selector: string | JQuery, visible: boolean): JQuery { let target = $(selector); if (visible) { target.addClass("ui-panel-visible"); } else { target.removeClass("ui-panel-visible"); } return target; } /* * 高さ設定 */ export function setFixedHeight(selector: string | JQuery, height: number): JQuery { let target = $(selector); if (target.hasClass("ui-panel-fixed")) { let inner = target.children(".ui-panel-inner"); inner.outerHeight(height - inner[0].offsetTop).css("overflow-y", "auto"); } return target; } }
「開く」、「閉じる」と強制表示、内側の高さ設定(スクロール用)
いくつかのモードが用意されていますがオーバーレイ以外使用しません
cssのその分だけ用意します
/Src/cm.css
/* Panel */ div.ui-panel { z-index: 1001; } div.ui-panel.ui-panel-display-overlay.ui-panel-position-left { border-right: 1px solid #ddd; } div.ui-panel.ui-panel-display-overlay.ui-panel-position-right { border-left: 1px solid #ddd; } /* Panel Visibled */ .ui-page > div.ui-panel.ui-panel-display-overlay.ui-panel-visible { /* overlay only */ clip: auto; width: 17em; visibility: visible; -webkit-transform: translate3d(0,0,0); -moz-transform: translate3d(0,0,0); -ms-transform: translate3d(0,0,0); -o-transform: translate3d(0,0,0); transform: translate3d(0,0,0); } .ui-page > div.ui-panel.ui-panel-display-overlay.ui-panel-visible.ui-panel-position-left { left: 0; right: auto; } .ui-page > div.ui-panel.ui-panel-display-overlay.ui-panel-visible.ui-panel-position-left ~ .ui-header, .ui-page > div.ui-panel.ui-panel-display-overlay.ui-panel-visible.ui-panel-position-left ~ .ui-content, .ui-page > div.ui-panel.ui-panel-display-overlay.ui-panel-visible.ui-panel-position-left ~ .ui-footer { margin-left: 17em; width: auto; } .ui-page > div.ui-panel.ui-panel-display-overlay.ui-panel-visible.ui-panel-position-right { right: 0; left: auto; } .ui-page > div.ui-panel.ui-panel-display-overlay.ui-panel-visible.ui-panel-position-right ~ .ui-header, .ui-page > div.ui-panel.ui-panel-display-overlay.ui-panel-visible.ui-panel-position-right ~ .ui-content, .ui-page > div.ui-panel.ui-panel-display-overlay.ui-panel-visible.ui-panel-position-right ~ .ui-footer { margin-right: 17em; width: auto; }
サンプルのhtmlです
/Views/Mobile/Index.html
<!DOCTYPE html> <html> <head> <title>Home</title> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1" /> <meta charset="utf-8" /> <link rel="stylesheet" href="@Url.Content("~/Content/jquery.mobile-1.4.5.min.css")" /> <link rel="stylesheet" href="@Url.Content("~/Src/cm.css")" /> <link rel="stylesheet" href="@Url.Content("~/Src/app.css")" /> <script type="text/javascript" src="@Url.Content("~/Scripts/jquery-2.1.3.min.js")"></script> <script type="text/javascript" src="@Url.Content("~/Scripts/jquery.mobile-1.4.5.min.js")"></script> <script type="text/javascript" src="@Url.Content("~/Src/cm.js")"></script> <script type="text/javascript" src="@Url.Content("~/Src/mobile.js")"></script> <style type="text/css"> .ui-header > .ui-title { background-color: Red; color: white; text-shadow: none; } .ui-btn-active{ background-color: Red !important; text-shadow:none !important; } </style> </head> <body class="ui-nodisc-icon ui-alt-icon"> <div data-role="page" id="page1"> <div data-role="panel" data-position="left" data-display="overlay" data-position-fixed="true" id="menu-left"> <ul data-role="listview"> <li><a href="#">AAAAAAAAAA</a></li> <li><a href="#">BBBBBBBBBB</a></li> <li><a href="#">CCCCCCCCCC</a></li> <li><a href="#">DDDDDDDDDD</a></li> <li><a href="#">EEEEEEEEEE</a></li> <li><a href="#">FFFFFFFFFF</a></li> <li><a href="#">GGGGGGGGGG</a></li> <li><a href="#">HHHHHHHHHH</a></li> <li><a href="#">IIIIIIIIII</a></li> <li><a href="#">JJJJJJJJJJ</a></li> <li><a href="#">KKKKKKKKKK</a></li> </ul> </div> <div data-role="panel" data-position="right" data-display="overlay" id="menu-right"> <ul data-role="listview"> <li><a href="#">AAAAAAAAAA</a></li> <li><a href="#">BBBBBBBBBB</a></li> <li><a href="#">CCCCCCCCCC</a></li> <li><a href="#">DDDDDDDDDD</a></li> <li><a href="#">EEEEEEEEEE</a></li> <li><a href="#">FFFFFFFFFF</a></li> <li><a href="#">GGGGGGGGGG</a></li> <li><a href="#">HHHHHHHHHH</a></li> <li><a href="#">IIIIIIIIII</a></li> <li><a href="#">JJJJJJJJJJ</a></li> <li><a href="#">KKKKKKKKKK</a></li> </ul> </div> <div data-role="header" data-position="fixed" data-fullscreen="false" data-tap-toggle="false"> <h1>Header</h1> <a href="#" class="ui-btn ui-btn-icon-notext ui-icon-carat-l ui-btn-left" cmd="left"></a> <div class="ui-right-panel"> <a href="#" class="ui-btn ui-btn-icon-notext ui-icon-bars ui-toolbtn"></a> <a href="#" class="ui-btn ui-btn-icon-notext ui-icon-carat-r" cmd="right"></a> </div> <div class="ui-toolbar" id="page1_toolbar1"> <div class="ui-left-panel"> <a href="#" class="ui-btn ui-btn-icon-notext ui-icon-star"></a> <a href="#" class="ui-btn ui-btn-icon-notext ui-icon-gear"></a> <a href="#" class="ui-btn ui-btn-icon-notext ui-icon-search"></a> <a href="#" class="ui-btn ui-btn-icon-notext ui-icon-edit"></a> </div> <div class="ui-right-panel"> <a href="#" class="ui-btn ui-btn-icon-notext ui-icon-bullets"></a> <a href="#" class="ui-btn ui-btn-icon-notext ui-icon-camera"></a> </div> </div> <div data-role="navbar"> <a href="#" class="ui-btn ui-btn-active">ホーム</a> <a href="#">設定</a> <a href="#">ヘルプ</a> <a href="#">問い合わせ</a> </div> </div> <div role="main" class="ui-content"> <ul data-role="listview" data-icon="false"> <li> <a href="#"> <img src=@Url.Content("~/imgs/album-bb.jpg")> <h2>Broken Bells</h2> <p>Broken Bells</p> </a> </li> <li> <img src=@Url.Content("~/imgs/album-hc.jpg")> <h2>Warning</h2> <p>Hot Chip</p> </li> <li> <a href="#"> <img src=@Url.Content("~/imgs/album-p.jpg")> <h2>Wolfgang Amadeus Phoenix</h2> <p>Phoenix</p> </a> </li> <li> <a href="#"> <img src=@Url.Content("~/imgs/album-bb.jpg")> <h2>Broken Bells</h2> <p>Broken Bells</p> </a> </li> <li> <img src=@Url.Content("~/imgs/album-hc.jpg")> <h2>Warning</h2> <p>Hot Chip</p> </li> <li> <a href="#"> <img src=@Url.Content("~/imgs/album-p.jpg")> <h2>Wolfgang Amadeus Phoenix</h2> <p>Phoenix</p> </a> </li> </ul> </div> <div data-role="footer" data-position="fixed" data-fullscreen="false" data-tap-toggle="false"> <div class="ui-toolbar"> <div class="ui-left-panel"> <a href="#" class="ui-btn ui-btn-icon-notext ui-icon-star"></a> <a href="#" class="ui-btn ui-btn-icon-notext ui-icon-gear"></a> <a href="#" class="ui-btn ui-btn-icon-notext ui-icon-search"></a> <a href="#" class="ui-btn ui-btn-icon-notext ui-icon-edit"></a> </div> <div class="ui-right-panel"> <a href="#" class="ui-btn ui-btn-icon-notext ui-icon-bullets"></a> <a href="#" class="ui-btn ui-btn-icon-notext ui-icon-camera"></a> </div> </div> <div data-role="navbar"> <a href="#" class="ui-btn ui-btn-active">ホーム</a> <a href="#">設定</a> <a href="#">ヘルプ</a> <a href="#">問い合わせ</a> </div> </div> </div> </body> </html>
パネルは左右を用意、やはりPage内に配置します
mobile.tsを用意します
/Src/mobile.ts
/// <reference path="../scripts/typings/jquery/jquery.d.ts" /> /// <reference path="../scripts/typings/jquerymobile/jquerymobile.d.ts" /> namespace Mobile { "use strict"; /* * ページ表示前 */ $(document).on("pagecontainerbeforeshow", function (event: Event, ui: any) { }); namespace Page1 { /* * ページ表示後 /*/ $(document).on("pagecontainershow", function (event: Event, ui: any) { }); } }
ソースの基本構造です
namespace html名 {
namespace ページ名 {...}
namespace ページ名 {...}
namespace ページ名 {...}
}
ページ表示イベントはPagecontainer Widgetのものを使用します
スパゲッティ化しないようにページ毎に用意します
Pagecontainerやwindow系のイベントはフィルタが聞かないようなので
$(document).on("pagecontainershow", function (event: Event, ui: any) { if (cm.getActivePageId() !== "page1") { return; } // 以下、ページ固有処理 });
と、内部でフィルタします
サンプルは幅をウィンドウ広げていくと、サイドパネルが左、右と表示されていくようにします
レスポンシブにはMediaQueryを使用します
条件設定はCSSと同じになります
/Src/mobile.ts
/// <reference path="../scripts/typings/jquery/jquery.d.ts" /> /// <reference path="../scripts/typings/jquerymobile/jquerymobile.d.ts" /> namespace Mobile { "use strict"; namespace mq { let mm = window.matchMedia("(min-width:28em) and (min-height:28em)"); mm.addListener(function (event: MediaQueryList) { update(); }); export function isMatch(): boolean { return mm.matches; } /* * パネルL */ export namespace PanelL { let panelL = window.matchMedia("(min-width:55em)"); panelL.addListener(function (event: MediaQueryList) { update(); }); export function isVisible(): boolean { return panelL.matches; } } /* * パネルR */ export namespace PanelR { let panelR = window.matchMedia("(min-width:80em)"); panelR.addListener(function (event: MediaQueryList) { update(); }); export function isVisible(): boolean { return panelR.matches; } } /* * 更新 */ export function update() { if (mm.matches) { $(".ui-header .ui-toolbar").resetDisplay(); $(".ui-header .ui-toolbtn").hide(); } else { $(".ui-header .ui-toolbar").hide(); $(".ui-header .ui-toolbtn").resetDisplay(); } $(document).trigger("mq_responsive"); } } /* * 表示前 */ $(document).on("pagecontainerbeforeshow", function (event: Event, ui: any) { mq.update(); }); namespace Page1 { let _panelLeft: JQuery; let _panelRight: JQuery; $(document).on("mq_responsive", function (event: Event) { if (cm.getActivePageId() !== "page1") { return; } Panel.setVisible(_panelLeft, mq.PanelL.isVisible()); Panel.setVisible(_panelRight, mq.PanelR.isVisible()); }); $(document).on("pagecontainershow", function (event: Event, ui: any) { if (cm.getActivePageId() !== "page1") { return; } // サイドパネル _panelLeft = $("#menu-left"); _panelRight = $("#menu-right"); $(window).resize(); mq.update(); }); /* * ヘッダボタン押下 */ $(document).on("click", "#page1 > .ui-header .ui-btn", function (event: Event) { let cmd = $(this).attr("cmd"); switch (cmd) { case "left": Panel.open(_panelLeft); break; case "right": Panel.open(_panelRight); break; } }); $(window).on("resize", function (event: Event) { if (cm.getActivePageId() !== "page1") { return; } // サイドパネルの高さ更新 let h = $(window).outerHeight(); Panel.setFixedHeight(_panelLeft, h); Panel.setFixedHeight(_panelRight, h); }); } }
しきい値(28em, 55em,80em)をまたぐ度に"mq_responsive"が発生します
28emを跨いでui-toolbarとui-toolbtnのどちらかを表示するようにしてみました
ui-toolbtnにメニューでもつけるべきなのですがそこはスルーで
addListenerしているのでグローバルにないと二重登録されるかもしれません
リサイズではPanelの内部の高さを設定しています