2016-02-25 28 views
2

我想要一個按鈕,如果按下的時間長於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>

回答

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>

+0

感謝您的輸入。我仍然有與模擬器相同的行爲 - > mouseup被中斷,也許Ionic在這裏有交互。但是,在我的iPhone上,mouseup事件被觸發,但觸發時會觸發mousedown,而不是touchstart,並在mouseup事件之前執行。 – Chris

0

不太清楚角,但使用純JavaScript我不喜歡這樣。

獲取時,按下按鈕,當前時間和當前時間的按鈕使用時釋放:

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

。減去兩個,如果兩者之間的差大於3000,然後它被按下超過3秒。

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; 
      } 
     }; 
    } 
}; 
}]); 
相關問題