根据按钮的按下时间将两个功能绑定到按钮

时间:2016-02-25 09:41:17

标签: javascript angularjs

如果按下的时间超过3秒,我想要一个调用不同功能的按钮。以下代码适用于鼠标事件,但在具有触摸事件的移动设备上失败:

angular.module('myApp', []).controller('myCtrl', function($scope, $timeout) {

  var mapService = {
    setHome: function() {
      console.log("setHome called");
    },

    goHome: function() {
      console.log("goHome called");
    }
  };
  
  var _homeDownTimeout = null;
  var _homeWasSet = false;

  $scope.homeDown = function() {
    _homeDownTimeout = $timeout(function() {
      mapService.setHome();
      _homeWasSet = true;
    }, 3000);
  };

  $scope.homeUp = function() {
    if (_homeDownTimeout) {
      $timeout.cancel(_homeDownTimeout);
    }
    if (!_homeWasSet) {
      mapService.goHome();
    } else {
      _homeWasSet = false;
    }
  };

});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.0/angular.min.js"></script>
<div ng-app="myApp" ng-controller="myCtrl">

  <button class="button icon ion-home button-map" ng-mousedown="homeDown()" ng-mouseup="homeUp()">HOME</button>

</div>

3 个答案:

答案 0 :(得分:1)

在Chrome中使用移动模拟器,看起来问题不在于代码,而在于触摸按住它时行为是选择元素,这会中断mouseup事件。

简单修复可能是在按钮CSS中设置user-select:none,如this answer中所述。

angular.module('myApp', []).controller('myCtrl', function($scope, $timeout) {

  var mapService = {
    setHome: function() {
      console.log("setHome called");
    },

    goHome: function() {
      console.log("goHome called");
    }
  };
  
  var _homeDownTimeout = null;
  var _homeWasSet = false;

  $scope.homeDown = function() {
    _homeDownTimeout = $timeout(function() {
      mapService.setHome();
      _homeWasSet = true;
    }, 3000);
  };

  $scope.homeUp = function() {
    if (_homeDownTimeout) {
      $timeout.cancel(_homeDownTimeout);
    }
    if (!_homeWasSet) {
      mapService.goHome();
    } else {
      _homeWasSet = false;
    }
  };

});
button {
  -webkit-touch-callout: none; /* iOS Safari */
  -webkit-user-select: none;   /* Chrome/Safari/Opera */
  -khtml-user-select: none;    /* Konqueror */
  -moz-user-select: none;      /* Firefox */
  -ms-user-select: none;       /* IE/Edge */
  user-select: none;           /* non-prefixed version, currently
                                  not supported by any browser */
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.0/angular.min.js"></script>
<div ng-app="myApp" ng-controller="myCtrl">

  <button class="button icon ion-home button-map" ng-mousedown="homeDown()" ng-mouseup="homeUp()">HOME</button>

</div>

答案 1 :(得分:0)

不太确定角度,但使用纯javascript我会这样做。

获取按下按钮时的当前时间以及使用以下方式释放按钮的当前时间:

var Time = new Date().getTime();

对两者进行减法,如果两者之间的差异大于3000,那么它被按下的时间超过3秒。

答案 2 :(得分:0)

我现在写了一个指令。经过Chrome,FF和iPhone测试。问题在于iPhone触摸和鼠标事件被触发(按此顺序),所以我不得不在触发事件被触发后解除鼠标事件的绑定。

HMTL:

<button class="button icon ion-home button-map" ng-holdclick="mapService.goHome(),mapService.setHome(),3000"></button>

JS:

app.directive("ngHoldclick", ['$timeout', function ($timeout) {
return {
    controller: function ($scope, $element, $attrs) {
        $element.bind('touchstart', onTouchStart);
        $element.bind('touchend', onTouchEnd);
        $element.bind('mousedown', onMouseDown);
        $element.bind('mouseup', onMouseUp);
        var params = $element.attr('ng-holdclick').split(",");
        var touchStartTimeout = null;
        var secondFunctionWasCalled = false;
        function onTouchStart(event) {
            $element.unbind('mousedown', onMouseDown);
            $element.unbind('mouseup', onMouseUp);
            $scope.$event = event;
            secondFunctionWasCalled = false;
            if (touchStartTimeout) {
                $timeout.cancel(touchStartTimeout);
            }
            touchStartTimeout = $timeout(function () {
                $scope.$apply(params[1]);
                secondFunctionWasCalled = true;
            }, params[2]);
        };
        function onMouseDown(event) {
            $element.unbind('touchstart', onTouchStart);
            $element.unbind('touchend', onTouchEnd);
            $scope.$event = event;
            secondFunctionWasCalled = false;
            if (touchStartTimeout) {
                $timeout.cancel(touchStartTimeout);
            }
            touchStartTimeout = $timeout(function () {
                $scope.$apply(params[1]);
                secondFunctionWasCalled = true;
            }, params[2]);
        };
        function onTouchEnd(event) {
            $scope.$event = event;
            if (touchStartTimeout) {
                $timeout.cancel(touchStartTimeout);
            }
            if (!secondFunctionWasCalled) {
                $scope.$apply(params[0]);
            } else {
                secondFunctionWasCalled = false;
            }
        };
        function onMouseUp(event) {
            $scope.$event = event;
            if (touchStartTimeout) {
                $timeout.cancel(touchStartTimeout);
            }
            if (!secondFunctionWasCalled) {
                $scope.$apply(params[0]);
            } else {
                secondFunctionWasCalled = false;
            }
        };
    }
};
}]);