アプリカンブログ

HTML5でiOS/Androidアプリが開発できるプラットフォーム、アプリカンのブログです。

Backbone.js + BackStackでスマホアプリ風画面遷移を実現

スマホアプリとこれまでのWebアプリケーションで大きく異なるのは画面遷移にあるのではないでしょうか。スマートフォンアプリではタップして上下左右から新しい画面がアニメーションしながら表示されるのが通常です。このような操作をWebアプリで実装するのは大変ですし、イベントハンドリングが残っているとメモリが解放されずにメモリリークにつながる可能性もあります。

有名なところではAngularJSを使ったIonicなどはフレームワーク側で画面遷移を実現できるようになっています。今回は同じくWebフロントエンドフレームワークとして知られるBackbone.jsとその画面遷移ライブラリであるBackStackを組み合わせてスムーズな画面遷移を実現してみます。

必要なもの

今回はこれに組み合わせてBootstrapのUIを使っています。

index.htmlを作成

HTMLの画面は次のようになります。

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <meta name="description" content="">
    <meta name="author" content="">
    <title>Signin Template for Bootstrap</title>
    <link href="css/bootstrap.min.css" rel="stylesheet">
    <link href="css/style.css" rel="stylesheet">
  </head>

  <body>
    <!-- HTMLコンテンツ -->
    <div class="container"></div>
    
    <!-- ライブラリ読み込み -->
    <script src="js/jquery-2.1.3.min.js"></script>
    <script src="js/underscore-min.js"></script>
    <script src="js/backbone-min.js"></script>
    <script src="js/backstack.js"></script>
    <script src="js/app.js"></script>
    
    <!-- ファーストビュー用のテンプレート -->
    <script type="text/template" id="first">
      <form class="form-signin" role="form">
        <h2 class="form-signin-heading">Please sign in</h2>
        <label for="inputEmail" class="sr-only">Email address</label>
        <input type="email" id="inputEmail" class="form-control" placeholder="Email address" required autofocus>
        <label for="inputPassword" class="sr-only">Password</label>
        <input type="password" id="inputPassword" class="form-control" placeholder="Password" required>
        <div class="checkbox">
          <label>
            <input type="checkbox" value="remember-me"> Remember me
          </label>
        </div>
        <button class="btn btn-sign-in btn-lg btn-primary btn-block" type="submit">Sign in</button>
      </form>
    </script>

    <!-- クリックした後のテンプレート -->
    <script type="text/template" id="second">
      <div class="main row">
    <div class="col-md-6 col-md-offset-3">
      <h1>Logged in!</h1>
      <button class="btn btn-log-out">Log out</button>
    </div>
      </div>
    </script>
  </body>
</html>

HTMLコンテンツは初期表示の時点では何もありません。埋め込み表示されるHTMLはテンプレートとして定義してあります。

app.jsの作成

Webアプリケーションの制御を行う js/app.js は次のようになります。

$(function() {
  var FirstView, SecondView, stackNavigator;
  FirstView = Backbone.View.extend({
    events: {
      'click .btn-sign-in': 'btnNext_clickHandler'
    },
    render: function() {
      this.$el.html($("#first").html());
      return this;
    },
    btnNext_clickHandler: function(event) {
      stackNavigator.pushView(SecondView);
    }
  });
  SecondView = Backbone.View.extend({
    events: {
      'click .btn-log-out': 'btnPrev_clickHandler'
    },
    render: function() {
      this.$el.html($("#second").html());
      return this;
    },
    btnPrev_clickHandler: function(event) {
      var slide;
      slide = new BackStack.SlideEffect({
        direction: 'rigth'
      });
      stackNavigator.popView(slide);
    }
  });
  stackNavigator = new BackStack.StackNavigator({
    el: '.container'
  });
  stackNavigator.pushView(FirstView, {}, new BackStack.NoEffect);
});

FirstViewおよびSecondViewはBackbone.Viewになります。そして、重要なのは次の行になります。

stackNavigator = new BackStack.StackNavigator({
  el: '.container'
});
stackNavigator.pushView(FirstView, {}, new BackStack.NoEffect);

BackStack.StackNavigatorというのがBackStackが定義する画面遷移のライブラリになります。それが .container 以下のコンテンツを差し替える仕組みです。

stackNavigator.pushView(FirstView, {}, new BackStack.NoEffect);

この行が実際にビュー(FirstView)を差し込んでいます。3つめの引数 new BackStack.NoEffect は初期表示なので何のエフェクトも行わないという指定になります。

この画面は次のように表示されます。

初期表示

このビューは次のように定義しています。

FirstView = Backbone.View.extend({
  events: {
    'click .btn-sign-in': 'btnNext_clickHandler'
  },
  render: function() {
    this.$el.html($("#first").html());
    return this;
  },
  btnNext_clickHandler: function(event) {
    stackNavigator.pushView(SecondView);
  }
});

.btn-sign-in をクリックすると、pushViewでSecondViewに画面遷移の指定を行っています。ボタンをクリックすると次のように表示されます。

2つめの画面

このビューは次のように定義されています。

SecondView = Backbone.View.extend({
  events: {
    'click .btn-log-out': 'btnPrev_clickHandler'
  },
  render: function() {
    this.$el.html($("#second").html());
    return this;
  },
  btnPrev_clickHandler: function(event) {
    var slide;
    slide = new BackStack.SlideEffect({
      direction: 'rigth'
    });
    stackNavigator.popView(slide);
  }
});

こちらは左から右に画面が流れるエフェクトが指定されていますので、Backボタン相当の処理が可能になっています。

実際に操作したアニメーションGIFになります。


スマートフォン用UIフレームワークではこの手の処理があらかじめ実装されていますが、UI周りまで複雑に影響を受けやすくなっています。使い慣れたフレームワークであったり、大型なWebアプリケーションを構築する際には画面遷移だけに特化したライブラリを使いたくなるでしょう。

BackStackはBackbone.jsでスマートフォン用アプリ(ハイブリッドアプリ)を作る際の一つの選択肢になりそうです。ハイブリッドアプリ開発の際にはぜひアプリカンとともにお使いください!

アプリカン | アプリ開発支援プラットフォーム