Onsen UI ユーザの皆さん、こんにちは。

この記事では Onsen UI 2.4.0 および 2.5.0 で追加された

  • エッジスワイプ (2.5.0)
  • <template> 要素をサポート (2.4.0)
  • <ons-page> 内への <script> 要素の記述に対応 (2.4.0)
  • 外部ファイルのキャッシュとプリロード (2.4.0)

の4つの新機能についてご説明します。

エッジスワイプ (2.5.0)

Onsen UI 2.5.0 以上では、<ons-navigator>swipeable 属性をつけることで、エッジスワイプ機能が有効になります。
この機能を有効にすると、バックボタンを押す代わりに、ページ左端をスワイプすることで前のページに戻ることができるようになります。

See the Pen Onsen UI 2.5.0 - Swipe to pop by Naoki Matagawa (@asial-matagawa) on CodePen.

また、オプションとして、swipe-target-width 属性と swipe-threshold 属性が用意されています。

swipe-target-width 属性を利用すると、画面左端からのスワイプの有効範囲を指定できます。指定可能な値は、正のピクセル値です(デフォルト値は 20px)。

swipe-threshold 属性を利用すると、ページの pop に必要なスワイプ量を指定できます。指定可能な値は、0 から 1.0 の小数値です(デフォルト値は 0.2)。

以下に swipe-target-width 属性と swipe-threshold 属性の使用例を示します。

See the Pen Onsen UI 2.5.0 - Swipe to pop - swipe-target-width & swipe-threshold by Naoki Matagawa (@asial-matagawa) on CodePen.

なお、Material Design 版の <ons-navigator> では、
swipeable 属性をつけてもエッジスワイプは有効になりません。
Material Design にはエッジスワイプの概念がないためです。

強制的にエッジスワイプを有効にするには、swipeable="force" と記述してください。
その際、slide-md 以外の遷移アニメーション(デフォルト値の lift-md など)を指定すると不自然な UI になってしまいますのでご注意ください。

See the Pen Onsen UI 2.5.0 - Swipe to pop - swipeable="force" in Material Design by Naoki Matagawa (@asial-matagawa) on CodePen.

AngularJS 1.x バインディング, Angular 2+ バインディングをお使いの方は
上記の例と同じようにそのまま swipeable, swipe-target-width, swipe-threshold 属性を記述してください。

React バインディングをお使いの方は、<Navigator> をご利用の場合は swipeable, swipe-target-width, swipe-threshold prop を記述してください。
<RouterNavigator> をご利用の場合は、 swipeable, swipe-target-width, swipe-threshold prop の記述に加えて、このコードを参考に swipePop prop を記述してください。

Vue バインディングをお使いの方は v-ons-navigatorswipeable, swipe-target-width, swipe-threshold 属性を記述してください。

<template>要素をサポート (2.4.0)

エッジスワイプの例でもお見せしたように、Onsen UI 2.4.0 以上では <template> でページを定義できるようになりました。

<template id="page1.html">
  <ons-page>
    <ons-toolbar>
      <div class="center">Page</div>
    </ons-toolbar>
    <div class="background"></div>
    <div class="content">
      <p>Content here</p>
    </div>
  </ons-page>
</template>

<template> 要素は Android 4.4 以上, iOS 9.0 以上でご利用可能です。

Onsen UI 2.3.x までで提供していた <ons-template> 要素は後方互換性を考慮して残してありますが、ons-template 要素を利用するメリットは特にないため、新しいプロジェクトを始める際は <template> 要素を利用することをお勧めします。

<ons-page>内への<script>要素の記述に対応 (2.4.0)

Onsen UI 2.4.0 以上では、<ons-page> が DOM ツリーに追加された際の処理を、<script> 要素の形で <ons-page> 内部に直接書けるようになりました。
また、onInit, onShow, onHide, onDestroy の4つのプロパティが追加されました。
これらを組み合わせることで、以下のようにページの HTML 構造と振る舞いを同時に定義することができます。

See the Pen Onsen UI 2.4.0 - <script> in <ons-page> by Naoki Matagawa (@asial-matagawa) on CodePen.

ただし、注意点として、<script> 要素は <ons-page> 要素の 直下の階層1つだけ 記述してください。
また、<ons-page> をテンプレートの中に記述する場合は、<ons-template> 要素ではなく <template> 要素を使用してください。<ons-template> 要素を使用すると、<ons-page> が navigator や splitter によって読み込まれる前に <script> 要素内のコードが動作してしまいます。

外部ファイルのキャッシュとプリロード (2.4.0)

ご存知の通り、ons-navigator#pushPageons-splitter-content#load には、外部ファイルを読み込む機能が付いています。しかし、同じ外部ファイルに何度もリクエストが送られるのはパフォーマンス上問題があります。そのため、Onsen UI 2.4.0 以上では、一度読み込んだ外部ファイルは自動的にキャッシュされます

しかし、まだ問題は残っています。外部ファイルへの最初の HTTP リクエストを pushPage や load のタイミングで行うと、通信速度の遅い端末やサーバにおいてパフォーマンスの問題が発生します。そこで Onsen UI 2.4.0 以上では、外部ファイルへの HTTP リクエストを事前に行うことのできる ons.preload 関数が提供されています

ons.preload 関数は以下のように使用します。
ons.preload 関数は非同期関数であり、外部ファイルを読み込み終えたタイミングで Promise が resolve されます。

<head>
  ...
  <script src="onsenui.js"></script>
  <script>
    ons.preload([
      'page2.html', // You can preload multiple files at a time
      'page3.html',
      'page4.html'
    ])
    .then(function(){
      console.log('All external files have been preloaded');
    })
    .catch(function(){
      console.error('Failed to preload external templates');
    });
  </script>
</head>
<body>
  <ons-navigator id="nav" page="page1.html">
  </ons-navigator>

  <template id="page1.html">
    <ons-page>
      <ons-toolbar>
        <div class="center">Page 1</div>
      </ons-toolbar>

      <!-- `pushPage` causes no HTTP request since page2.html is preloaded -->
      <ons-button
        onclick="document.getElementById('nav').pushPage('page2.html')">
        Next Page
      </ons-button>
    </ons-page>
  </template>
</body>

ons.preload 関数は必ずしも <head> 要素内で実行する必要はありません。
状況に合わせて、お好きな場所でご利用ください。


Onsen UIはハイブリッドアプリ向けUIを作成するためのオープンソースのライブラリです。詳細はGitHubページをご確認ください。
また、Onsen UIを応援してくれる方はぜひスター(★)をポチッとお願いいたします。