如何启用离子多点触控事件

时间:2015-03-06 17:05:01

标签: javascript android angularjs ionic-framework

我正在开发一个简单的离子应用程序,部分应用程序要求您一次按下两个按钮。我已经建立了这样的逻辑:

<!--yT stands for yourThumb, pT stands for partnersThumb -->


<a class="icon ion-qr-scanner lg-txt" on-hold="Global.thumbHoldManager('yT',true)" on-release="Global.thumbHoldManager('yT',false, true)"></a>

<a class="icon ion-qr-scanner lg-txt" on-hold="Global.thumbHoldManager('pT',true)" on-release="Global.thumbHoldManager('pT',false, true)"></a>

我的控制器上有一个方法,它使用我创建的服务处理此事件

var globalCtrl = function (clickHandler, $timeout) {
  var self = this;
  this.clickHandler = clickHandler;
  this.timeout = $timeout;
  this.readyState = clickHandler.ready;
  this.showInstruction = false;

  clickHandler.watchForReady();

};

globalCtrl.prototype.thumbHoldManager = function(which, what, up) {
    this.clickHandler.setClickState(which, what);
    var self = this;

    if (up) {
        this.clickHandler.stopWatching();
    }

    if (!this.readyState) {
        this.instruction = "Hold both thumbs in place to scan"
        if (!this.showInstruction) {
                this.showInstruction = true;
                self.timeout(function() {
                self.showInstruction = false;
            }, 5000)
        }
    }
};

globalCtrl.$inject = ['clickHandler', '$timeout'];

服务clickHandler将api暴露给私有对象,该私有对象的作用是在按下按钮时跟踪,以及当按下两个按钮以导航到新URL时。

.factory('clickHandler', [
    '$interval',
    '$rootScope',
    '$location',
    function($interval, $rootScope, $location) {

    // Service logic
    // ...

        var clickState = {
            yT: false,
            pT: false,
            ready: false,
            watching: false,
            watcher: false
        };

    // Public API here

        return {
            setClickState: function(which, what) {
                clickState[which] = what;
            },

            getClickState: function(which) {
                return clickState[which]
            },

            getReadyState: function() {
                return ((clickState.yT) && (clickState.pT));
            },

            watchForReady: function() {
                var self = this;
                clickState.watching = $interval(function() {
                    clickState.ready = self.getReadyState();
                },50);

                clickState.watcher = $rootScope.$watch(function() {
                    return clickState.ready
                }, function redirect(newValue) {
                    if (newValue) {
                        self.stopWatching();
                        $location.path('/scan');
                    }
                })
            },

            stopWatching: function() {
                if (clickState.watching) {
                    $interval.cancel(clickState.watching);
                    clickState.watcher();
                    clickState.watching = false;
                    clickState.watcher = false;

                }
            }

        };
    }
])

我的代码没有任何错误,一切正常,观察者在hold事件中注册并在发布事件中取消注册。但无论我做什么,我似乎无法通过手机检测两个按钮上的按键。它总是一个或另一个,我不知道为什么。我无法在浏览器或模拟器中对此进行测试,因为不支持多点触控,如果没有,我也没有多点触控触控板。

2 个答案:

答案 0 :(得分:0)

以下是我实现自己的指令和服务的方法:

.factory('clickHandler', ['$interval', '$rootScope', '$location', '$document', function ($interval, $rootScope, $location, $document) {
// Service logic
// ...

$document = $document[0];



var
  touchStart,
  touchEnd;

touchStart = ('ontouchstart' in $document.documentElement) ? 'touchstart' : 'mousedown';
touchEnd = ('ontouchend' in $document.documentElement) ? 'touchend' : 'mouseup';

var clickState = {
  yT:         false,
  pT:         false,
  ready:      false,
  watching:   false,
  watcher:    false,
  startEvent: touchStart,
  endEvent:   touchEnd
};

// Public API here
return {
  setClickState: function (which, what) {
    clickState[which] = what;
  },

  getClickState: function (which) {
    return clickState[which]
  },

  getReadyState: function () {
    return ( (clickState.yT) && (clickState.pT) );
  },

  watchForReady: function () {
    var self = this;

    //prevent multiple redundant watchers

    if (clickState.watching) {
      return;
    }

    clickState.watching = $interval(function () {
      clickState.ready = self.getReadyState();
    }, 50);

    clickState.watcher = $rootScope.$watch(function () {
      return clickState.ready
    }, function redirect(newValue) {
      if (newValue) {
        self.stopWatching();
        $location.path('/scan');
      }
    })
  },

  stopWatching: function () {
    if (clickState.watching) {
      $interval.cancel(clickState.watching);
      clickState.watcher();
      clickState.watching = false;
      clickState.watcher = false;

    }
  },

  getTouchEvents: function () {
    return {
      start: clickState.startEvent,
      end:   clickState.endEvent
    }
  }




  };
}])

.directive('simultaneousTouch', ['clickHandler', '$document', function (clickHandler) {
  return {
    restrict: 'A',
    link:     function (scope, elem, attr) {
      var touchEvents = clickHandler.getTouchEvents();

      elem.on(touchEvents.start, function () {

        clickHandler.watchForReady();
        clickHandler.setClickState(attr.simultaneousTouch, true);
      });

      elem.on(touchEvents.end, function () {
        clickHandler.stopWatching();
        clickHandler.setClickState(attr.simultaneousTouch, false);
      })
    }
  }
}]);

答案 1 :(得分:0)

为了参考,从离子论坛交叉stankugo的答案。下面简单的解决方案完全是他的想法,我刚做了一点清理。

angular.module('xxxx').directive('multitouch', function () {
    return function(scope, element, attr) {
        element.on('touchstart', function() {
            scope.$apply(function() {
                scope.$eval(attr.multitouch);
            });
        });
    };
});

使用类似:

<div multitouch="handler()"></div>