2013年3月15日金曜日

スマートフォンなどでJavaScriptのクリックイベントが遅れるのを解消する(AngularJS)

nd-click="hoge($event)"としても、hogeの中で$eventを取得できません。

AngularJS1.1系にngMobileがあります。これが有効になるとスマートフォンでのクリックの遅延がなくなり、スワイプの利用も可能になります。
次期リリース版(1.2系)に含まれると思います。1.0系にバックポートするか1.1系を使うか、1.2系を待つのが良いと思います。
https://github.com/angular/angular.js/tree/master/src/ngMobile


スマートフォンやタブレットではJavaScriptのクリックイベントが少し遅れてくるようになっています。
普段なら自分でtouchstartイベントなどを拾って解決するところだと思いますが、AngularJSはng-clickというAngularJSの機能を使うので、その方法がそのままでは使えなさそうです。AngularJSライク?に解決したのでブログに残します。

タッチイベントが来たらクリックイベントを起こしています。
Gistにも書きました。

CoffeeScriptです。
app = angular.module('AngularStudy', []).directive 'ndClick', => ($scope, $element, $attrs) =>
  isTap = isTapped = false
  $element.bind 'click', => $scope.$apply $attrs['ndClick'] unless isTapped
  $element.bind 'touchstart', => isTap = true
  $element.bind 'touchmove', => isTap = false
  $element.bind 'touchend', => if isTap
    isTapped = true
    $scope.$apply $attrs['ndClick'], $element

一応CoffeeScriptをコンパイルしたJavaScriptも書いておきます。
var app,
  _this = this;

app = angular.module('AngularStudy', []).directive('ndClick', function() {
  return function($scope, $element, $attrs) {
    var isTap, isTapped;
    isTap = isTapped = false;
    $element.bind('click', function() {
      if (!isTapped) {
        return $scope.$apply($attrs['ndClick']);
      }
    });
    $element.bind('touchstart', function() {
      return isTap = true;
    });
    $element.bind('touchmove', function() {
      return isTap = false;
    });
    return $element.bind('touchend', function() {
      if (isTap) {
        isTapped = true;
        return $scope.$apply($attrs['ndClick'], $element);
      }
    });
  };
});

使い方は今までng-clickを書いていたところをnd-clickにするだけです。
<button nd-click="hoge()">ボタン</button>

パソコンとスマートフォンの差を吸収しているので、パソコンでもスマートフォンでもnd-clickだけでカバーできます。

nd-clickはnon delay clickです。

0 件のコメント:

コメントを投稿