AngularJS - Click & Tap Directives
by gavinfoley
HTML
<div ng-app="AppRoot">
<div ng-controller="DemoCtrl">
<div fast-click="fastclickout = 'fastclick ' + fastclickout" class="button">Fast Click</div>
<div>{{fastclickout}}</div>
<div ng-click="normalclickout = 'normalclick ' + normalclickout" class="button">Normal Click</div>
<div>{{normalclickout}}</div>
<div tap-or-click="taporclickout = 'taporclick ' + taporclickout" class="button">Tap Or Click</div>
<div>{{taporclickout}}</div>
</div>
</div>
CSS
.button {
padding:5px;
background-color:#cccccc;
border-radius:4px;
width:100px;
cursor: pointer;
}
div {
margin: 20px;
}
JavaScript
var AppRoot = angular.module('AppRoot', []);
AppRoot.controller('DemoCtrl', ['$scope', function (scope) {
scope.fastclickout = '';
}]);
AppRoot.directive('fastClick', ['$parse', function ($parse) {
return function (scope, element, attr) {
var fn = $parse(attr['fastClick']);
var initX, initY, endX, endY;
var elem = element;
var maxMove = 4;
elem.bind('touchstart', function (event) {
event.preventDefault();
initX = endX = event.touches[0].clientX;
initY = endY = event.touches[0].clientY;
elem.bind('touchend', onTouchEnd);
elem.bind('touchmove', onTouchMove);
});
function onTouchMove(event) {
endX = event.touches[0].clientX;
endY = event.touches[0].clientY;
};
function onTouchEnd(event) {
elem.unbind('touchmove');
elem.unbind('touchend');
if (Math.abs(endX - initX) > maxMove) return;
if (Math.abs(endY - initY) > maxMove) return;
scope.$apply(function () {
fn(scope, {
$event: event
});
});
};
};
}]);
AppRoot.directive("tapOrClick", [function () {
return function (scope, element, attrs) {
var tapped;
tapped = false;
element.bind("click", function () {
if (!tapped) {
return scope.$apply(attrs["tapOrClick"]);
}
});
element.bind("touchstart", function (event) {
return tapped = true;
});
element.bind("touchmove", function (event) {
tapped = false;
return event.stopImmediatePropagation();
});
return element.bind("touchend", function () {
if (tapped) {
return scope.$apply(attrs["tapOrClick"]);
}
});
};
}]);