Skip to content
This repository was archived by the owner on Apr 12, 2024. It is now read-only.

Commit 5a568b4

Browse files
robinboehmtbosch
authored andcommitted
feat(ngTouch): add optional ngSwipeDisableMouse attribute to ngSwipe directives to ignore mouse events.
This attribute is useful for text that should still be selectable by the mouse and not trigger the swipe action. This also adds an optional third argument to `$swipe.bind` to define the pointer types that should be listened to. Closes #6627 Fixes #6626
1 parent e9bc51c commit 5a568b4

File tree

4 files changed

+431
-382
lines changed

4 files changed

+431
-382
lines changed

src/ngTouch/directive/ngSwipe.js

+8-1
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,9 @@
1212
* Though ngSwipeLeft is designed for touch-based devices, it will work with a mouse click and drag
1313
* too.
1414
*
15+
* To disable the mouse click and drag functionality, add `ng-swipe-disable-mouse` to
16+
* the `ng-swipe-left` or `ng-swipe-right` DOM Element.
17+
*
1518
* Requires the {@link ngTouch `ngTouch`} module to be installed.
1619
*
1720
* @element ANY
@@ -101,6 +104,10 @@ function makeSwipeDirective(directiveName, direction, eventName) {
101104
deltaY / deltaX < MAX_VERTICAL_RATIO;
102105
}
103106

107+
var pointerTypes = ['touch'];
108+
if (!angular.isDefined(attr['ngSwipeDisableMouse'])) {
109+
pointerTypes.push('mouse');
110+
}
104111
$swipe.bind(element, {
105112
'start': function(coords, event) {
106113
startCoords = coords;
@@ -117,7 +124,7 @@ function makeSwipeDirective(directiveName, direction, eventName) {
117124
});
118125
}
119126
}
120-
});
127+
}, pointerTypes);
121128
};
122129
}]);
123130
}

src/ngTouch/swipe.js

+40-9
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,20 @@ ngTouch.factory('$swipe', [function() {
2525
// The total distance in any direction before we make the call on swipe vs. scroll.
2626
var MOVE_BUFFER_RADIUS = 10;
2727

28+
var POINTER_EVENTS = {
29+
'mouse': {
30+
start: 'mousedown',
31+
move: 'mousemove',
32+
end: 'mouseup'
33+
},
34+
'touch': {
35+
start: 'touchstart',
36+
move: 'touchmove',
37+
end: 'touchend',
38+
cancel: 'touchcancel'
39+
}
40+
};
41+
2842
function getCoordinates(event) {
2943
var touches = event.touches && event.touches.length ? event.touches : [event];
3044
var e = (event.changedTouches && event.changedTouches[0]) ||
@@ -38,6 +52,17 @@ ngTouch.factory('$swipe', [function() {
3852
};
3953
}
4054

55+
function getEvents(pointerTypes, eventType) {
56+
var res = [];
57+
angular.forEach(pointerTypes, function(pointerType) {
58+
var eventName = POINTER_EVENTS[pointerType][eventType];
59+
if (eventName) {
60+
res.push(eventName);
61+
}
62+
});
63+
return res.join(' ');
64+
}
65+
4166
return {
4267
/**
4368
* @ngdoc method
@@ -46,6 +71,9 @@ ngTouch.factory('$swipe', [function() {
4671
* @description
4772
* The main method of `$swipe`. It takes an element to be watched for swipe motions, and an
4873
* object containing event handlers.
74+
* The pointer types that should be used can be specified via the optional
75+
* third argument, which is an array of strings `'mouse'` and `'touch'`. By default,
76+
* `$swipe` will listen for `mouse` and `touch` events.
4977
*
5078
* The four events are `start`, `move`, `end`, and `cancel`. `start`, `move`, and `end`
5179
* receive as a parameter a coordinates object of the form `{ x: 150, y: 310 }`.
@@ -68,7 +96,7 @@ ngTouch.factory('$swipe', [function() {
6896
* as described above.
6997
*
7098
*/
71-
bind: function(element, eventHandlers) {
99+
bind: function(element, eventHandlers, pointerTypes) {
72100
// Absolute total movement, used to control swipe vs. scroll.
73101
var totalX, totalY;
74102
// Coordinates of the start position.
@@ -78,21 +106,24 @@ ngTouch.factory('$swipe', [function() {
78106
// Whether a swipe is active.
79107
var active = false;
80108

81-
element.on('touchstart mousedown', function(event) {
109+
pointerTypes = pointerTypes || ['mouse', 'touch'];
110+
element.on(getEvents(pointerTypes, 'start'), function(event) {
82111
startCoords = getCoordinates(event);
83112
active = true;
84113
totalX = 0;
85114
totalY = 0;
86115
lastPos = startCoords;
87116
eventHandlers['start'] && eventHandlers['start'](startCoords, event);
88117
});
118+
var events = getEvents(pointerTypes, 'cancel');
119+
if (events) {
120+
element.on(events, function(event) {
121+
active = false;
122+
eventHandlers['cancel'] && eventHandlers['cancel'](event);
123+
});
124+
}
89125

90-
element.on('touchcancel', function(event) {
91-
active = false;
92-
eventHandlers['cancel'] && eventHandlers['cancel'](event);
93-
});
94-
95-
element.on('touchmove mousemove', function(event) {
126+
element.on(getEvents(pointerTypes, 'move'), function(event) {
96127
if (!active) return;
97128

98129
// Android will send a touchcancel if it thinks we're starting to scroll.
@@ -126,7 +157,7 @@ ngTouch.factory('$swipe', [function() {
126157
}
127158
});
128159

129-
element.on('touchend mouseup', function(event) {
160+
element.on(getEvents(pointerTypes, 'end'), function(event) {
130161
if (!active) return;
131162
active = false;
132163
eventHandlers['end'] && eventHandlers['end'](getCoordinates(event), event);

test/ngTouch/directive/ngSwipeSpec.js

+18
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,24 @@ var swipeTests = function(description, restrictBrowsers, startEvent, moveEvent,
6666
expect($rootScope.swiped).toBe(true);
6767
}));
6868

69+
it('should only swipe given ng-swipe-disable-mouse attribute for touch events', inject(function($rootScope, $compile) {
70+
element = $compile('<div ng-swipe-left="swiped = true" ng-swipe-disable-mouse></div>')($rootScope);
71+
$rootScope.$digest();
72+
expect($rootScope.swiped).toBeUndefined();
73+
74+
browserTrigger(element, startEvent, {
75+
keys : [],
76+
x : 100,
77+
y : 20
78+
});
79+
browserTrigger(element, endEvent,{
80+
keys: [],
81+
x: 20,
82+
y: 20
83+
});
84+
expect(!!$rootScope.swiped).toBe(description !== 'mouse');
85+
}));
86+
6987
it('should pass event object', inject(function($rootScope, $compile) {
7088
element = $compile('<div ng-swipe-left="event = $event"></div>')($rootScope);
7189
$rootScope.$digest();

0 commit comments

Comments
 (0)