Angular UI RouterでA-Frameを使ったページを表示するとタッチスクロールが効かなくなる問題

以下の例はルート`/a`で通常のWebページ、ルート`/b`でA-Frameを使用したWebページを表示する簡単なサンプルです。

```html
<!DOCTYPE html>
<html ng-app="App">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width">
  <title>Example</title>
</head>

<body>
  <ui-view></ui-view>

  <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.6.0/angular.min.js"></script>
  <script src="//cdnjs.cloudflare.com/ajax/libs/angular-ui-router/0.3.2/angular-ui-router.min.js"></script>
  <script src="//aframe.io/releases/0.3.2/aframe.min.js"></script>
  <script>
    angular.module('App', ['ui.router'])
      .config(($stateProvider) => {
        $stateProvider
          // /a のルートを定義
          .state({
            name: 'a',
            url: '/a',

            // 適当に縦に長い内容にする
            template: `
            <a ui-sref="b">to B</a>
            <ul>
              <li ng-repeat="item in $ctrl.items">{{item.index}} : {{item.value}}</li>
            </ul>`,

            controller: function () {
              let items = [];
              for (let i = 0; i < 100; i++) {
                items.push({
                  index: i,
                  value: Math.floor(Math.random() * 100)
                });
              }
              this.items = items;
            },
            controllerAs: '$ctrl'
          })

          // /b のルートを定義
          .state({
            name: 'b',
            url: '/b',

            // ページ内でA-Frameを使用している
            template: `
              <a ui-sref="a">to A</a>
              <a-scene>
                <a-box color="#6173F4" position="0 0 -5"></a-box>
              </a-scene>
            `
          });
      })
      .run(($state) => {
        $state.go('a');
      });
  </script>
</body>

</html>
```

このページをモバイルデバイスで表示すると、最初に`/a`のページを表示している際は正常にスクロールできますが、**`/b`のページ(A-Frameのコンテンツ)を表示してからまた`/a`のページを表示した際に、タッチスクロールが効かなくなります。**

Chromeのデベロッパーツールで調べてみると、`/b`のページを表示した際に`<head>`の中にいくつかの要素が追加されることと、`<html>`要素に`a-html`クラスが、`<body>`要素に`a-body`クラスが追加されることがわかります。この辺がアヤシそうです。
ためしにデベロッパーツール上で追加された`<style>`要素を削除したり`a-html`,`a-body`のクラスを外したりすると再びタッチスクロールが効くようになりました！！

ただし、`<style>`の方を手動で削除してしまうと、再度`/b`のページを表示した際に`<style>`が挿入されず、正しく表示されません。一方`a-html`,`a-body`のクラスの方は手動で削除しても再度`/b`のページを表示した際に再度追加されます。
というわけで、**A-Frameを使ったページから離れるときに`a-html`,`a-body`クラスを削除する**ということができれば、問題は解決しそうです。

下記は`a-html`,`a-body`クラスを削除する実装をしたものです。だいぶ簡略化しているので、クロスブラウザ対応を考えたらもう少しちゃんとエラー処理しなきゃいけないかもしれません。
まぁ、そもそもA-Frameを使ってる時点でモダンブラウザ限定なわけですが…

```html
<!DOCTYPE html>
<html ng-app="App">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width">
  <title>Example</title>
</head>

<body>
  <ui-view></ui-view>

  <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.6.0/angular.min.js"></script>
  <script src="//cdnjs.cloudflare.com/ajax/libs/angular-ui-router/0.3.2/angular-ui-router.min.js"></script>
  <script src="//aframe.io/releases/0.3.2/aframe.min.js"></script>
  <script>
    angular.module('App', ['ui.router'])
      .config(($stateProvider) => {
        $stateProvider
          .state({
            name: 'a',
            url: '/a',
            template: `
            <a ui-sref="b">to B</a>
            <ul>
              <li ng-repeat="item in $ctrl.items">{{item.index}} : {{item.value}}</li>
            </ul>`,
            controller: function () {
              let items = [];
              for (let i = 0; i < 100; i++) {
                items.push({
                  index: i,
                  value: Math.floor(Math.random() * 100)
                });
              }
              this.items = items;
            },
            controllerAs: '$ctrl'
          })
          .state({
            name: 'b',
            url: '/b',
            template: `
              <a ui-sref="a">to A</a>
              <a-scene>
                <a-box color="#6173F4" position="0 0 -5"></a-box>
              </a-scene>
            `,
            controller: function ($scope) {
              // このページから離れる際にa-html,a-bodyクラスを削除する
              $scope.$on('$destroy', () => {
                document.querySelector('.a-html').classList.remove('a-html');
                document.querySelector('.a-body').classList.remove('a-body');
              });
            }
          });
      })
      .run(($state) => {
        $state.go('a');
      });
  </script>
</body>

</html>
```

## 追記

上記記事は古い1.x系のAngular Routerの話ですが、同じ現象は最新のAngular 5でも発生します。
この場合でも同様に、A-FrameのViewを持つコンポーネントの`ngOnDestroy`で同じ処理を行えば症状が改善します。

```ts
@Component({
  selector: 'app-vr-viewer',
  templateUrl: './viewer.component.html',
  styleUrls: ['./viewer.component.css']
})
export class VrViewerComponent implements OnDestroy {

  ngOnDestroy() {
    // タッチが効かなくなる問題を修正
    document.querySelector('.a-html').classList.remove('a-html')
    document.querySelector('.a-body').classList.remove('a-body')
  }

}
```