如果按下的时间超过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>
答案 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;
}
};
}
};
}]);