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

how to enable ionic multi-touch events

本文关键字:多点 触摸 事件 何启用 启用      更新时间:2023-09-26

我正在开发一个简单的ionic应用程序,该应用程序的一部分需要您同时按下两个按钮。我构建了这样的逻辑:

<!--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;
                }
            }
        };
    }
])

我在这个代码中没有任何错误,一切都正常工作,观察者在挂起事件中注册,在发布事件中未注册。但无论我做什么,我似乎都无法让手机检测到按下两个按钮。总是这样或那样,我不知道为什么。我无法在浏览器或模拟器中测试这一点,因为不支持多点触摸,如果支持的话,我也没有多点触摸触控板。

以下是我如何实现自己的指令和服务:

.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);
      })
    }
  }
}]);

为了参考,在离子论坛上交叉发布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>