Skip to content

Commit f3bd258

Browse files
author
Adam Bradley
committed
fix(tap): Prevent "clicking" when scrolling
1 parent ee2b768 commit f3bd258

File tree

2 files changed

+107
-29
lines changed

2 files changed

+107
-29
lines changed

Diff for: js/ext/angular/test/list.html

+99-21
Original file line numberDiff line numberDiff line change
@@ -8,20 +8,42 @@
88
<style>
99
#click-notify {
1010
position: absolute;
11+
top: 100px;
12+
left: 40%;
13+
z-index: 9997;
1114
display: none;
12-
top: 150px;
13-
left: 48%;
14-
z-index: 9999;
15+
padding: 8px;
1516
background: red;
17+
color: white;
18+
}
19+
#mousemove-notify {
20+
position: absolute;
21+
top: 140px;
22+
left: 40%;
23+
z-index: 9998;
24+
display: none;
25+
padding: 8px;
26+
background: orange;
27+
}
28+
#touchmove-notify {
29+
position: absolute;
30+
top: 180px;
31+
left: 40%;
32+
z-index: 9999;
33+
display: none;
34+
padding: 8px;
35+
background: yellow;
1636
}
1737
</style>
1838
</head>
1939
<body ng-controller="TestCtrl">
2040
<div id="click-notify">CLICK!</div>
21-
<ion-side-menus>
41+
<div id="mousemove-notify">Mouse Move!</div>
42+
<div id="touchmove-notify">Touch Move!</div>
43+
<!-- <ion-side-menus>
2244
2345
<ion-side-menu-content>
24-
46+
-->
2547
<ion-header-bar class="bar-positive">
2648
<div class="buttons">
2749
<button ng-click="toggleDelete()" class="button button-clear">{{ editBtnText }}</button>
@@ -35,7 +57,8 @@ <h1 class="title">List Tests</h1>
3557

3658
<ion-content class="has-header">
3759

38-
<ion-list show-delete="isDeletingItems"
60+
<ion-list
61+
show-delete="isDeletingItems"
3962
show-reorder="isReorderingItems"
4063
on-refresh-holding="refreshHolding()"
4164
on-refresh-opening="refreshOpening(ratio)"
@@ -52,7 +75,7 @@ <h1 class="title">List Tests</h1>
5275
option-buttons="optionButtons1">
5376

5477
<!-- shows that the item directive does not need attributes and can get values from the list attributes -->
55-
<ion-item item="item" ng-href="#" ng-click="itemClick()" class="item-thumbnail-left" ng-repeat="item in items" ng-class="{ active: item.isActive}">
78+
<ion-item item="item" ng-href="#" ng-click="itemClick(item)" class="item-thumbnail-left" ng-repeat="item in items" ng-class="{ active: item.isActive}">
5679
<img ng-src="{{item.face}}">
5780
<h2>{{item.from}}</h2>
5881
<p>{{item.text}}</p>
@@ -122,13 +145,13 @@ <h1>YELLOW {{slideBox.slideIndex}}</h1>
122145
</ion-list>
123146

124147
</ion-content>
125-
148+
<!--
126149
</ion-side-menu-content>
127150
128151
<ion-side-menu side="left">
129152
Left menu!
130153
</ion-side-menu>
131-
</ion-side-menus>
154+
</ion-side-menus> -->
132155

133156
<script>
134157
angular.module('navTest', ['ionic'])
@@ -141,14 +164,38 @@ <h1>YELLOW {{slideBox.slideIndex}}</h1>
141164

142165
// Build Mock Data
143166
$scope.items = [
144-
{ from: 'Ben', face: 'https://pbs.twimg.com/profile_images/378800000571933189/278e8e1b7871a115b95fc550cd07af40.png', text: 'Whoa, whoa, whoa. There’s still plenty of meat on that bone. Now you take this home, throw it in a pot, add some broth, a potato. Baby, you\'ve got a stew going.' },
145-
{ from: 'Adam', face: 'https://pbs.twimg.com/profile_images/2927292174/25b170ee2e3044fd936ad1319bc4b82d_bigger.jpeg', text: 'It Ain\'t Easy Being Cheesy' },
146-
{ from: 'Tim', face: 'https://pbs.twimg.com/profile_images/378800000290028838/ee3303b02223f25cb0f9b082b55b2eeb.jpeg', text: 'Baxter! You know I don\'t speak spanish!' },
147-
{ from: 'Brody', face: 'https://pbs.twimg.com/profile_images/378800000138067018/554c103ebf37c2ba3b923b8deea46b0d.jpeg', text: 'Sounds like some sort of marmalade' },
148-
{ from: 'Peter', face: 'https://pbs.twimg.com/profile_images/378800000238071493/08f76337bdc91b1e1e73a9d55c57a451.jpeg', text: 'A cooked goose for everyone!' },
149-
{ from: 'Max', face: 'https://pbs.twimg.com/profile_images/430001754747305984/qa5DFLgU.jpeg', text: 'Yes my dear man, more beans. oooohh' },
150-
{ from: 'Andy', face: 'https://pbs.twimg.com/profile_images/423294834229522433/BSlEOBYt.jpeg', text: 'I did it all for her' },
151-
{ from: 'Melissa', face: 'https://pbs.twimg.com/profile_images/412451928816111616/VZ3_md1N.jpeg', text: 'I think I want my money back' }
167+
{
168+
from: 'Ben',
169+
face: 'https://pbs.twimg.com/profile_images/378800000571933189/278e8e1b7871a115b95fc550cd07af40.png',
170+
text: 'Whoa, whoa, whoa. There’s still plenty of meat on that bone. Now you take this home, throw it in a pot, add some broth, a potato. Baby, you\'ve got a stew going.' },
171+
{
172+
from: 'Adam',
173+
face: 'https://pbs.twimg.com/profile_images/2927292174/25b170ee2e3044fd936ad1319bc4b82d_bigger.jpeg',
174+
text: 'It Ain\'t Easy Being Cheesy' },
175+
{
176+
from: 'Tim',
177+
face: 'https://pbs.twimg.com/profile_images/378800000290028838/ee3303b02223f25cb0f9b082b55b2eeb.jpeg',
178+
text: 'Baxter! You know I don\'t speak spanish!' },
179+
{
180+
from: 'Brody',
181+
face: 'https://pbs.twimg.com/profile_images/378800000138067018/554c103ebf37c2ba3b923b8deea46b0d.jpeg',
182+
text: 'Sounds like some sort of marmalade' },
183+
{
184+
from: 'Peter',
185+
face: 'https://pbs.twimg.com/profile_images/378800000238071493/08f76337bdc91b1e1e73a9d55c57a451.jpeg',
186+
text: 'A cooked goose for everyone!' },
187+
{
188+
from: 'Max',
189+
face: 'https://pbs.twimg.com/profile_images/430001754747305984/qa5DFLgU.jpeg',
190+
text: 'Yes my dear man, more beans. oooohh' },
191+
{
192+
from: 'Andy',
193+
face: 'https://pbs.twimg.com/profile_images/423294834229522433/BSlEOBYt.jpeg',
194+
text: 'I did it all for her' },
195+
{
196+
from: 'Melissa',
197+
face: 'https://pbs.twimg.com/profile_images/412451928816111616/VZ3_md1N.jpeg',
198+
text: 'I think I want my money back' }
152199
];
153200

154201

@@ -167,12 +214,14 @@ <h1>YELLOW {{slideBox.slideIndex}}</h1>
167214
};
168215

169216

170-
$scope.itemClick = function() {
171-
console.info('itemClick');
172-
document.getElementById('click-notify').style.display = 'block';
217+
$scope.itemClick = function(item) {
218+
var el = document.getElementById('click-notify');
219+
el.style.display = 'block';
220+
el.innerText = 'Click! ' + item.from;
221+
173222
setTimeout(function(){
174223
document.getElementById('click-notify').style.display = 'none';
175-
}, 500);
224+
}, 300);
176225
};
177226

178227
// Item Methods/Properties
@@ -216,6 +265,35 @@ <h1>YELLOW {{slideBox.slideIndex}}</h1>
216265
];
217266

218267
});
268+
269+
var mouseTimerId;
270+
function onMouseMove(e) {
271+
clearTimeout(mouseTimerId);
272+
mouseTimerId = setTimeout(function(){
273+
var el = document.getElementById('mousemove-notify');
274+
el.style.display = 'block';
275+
clearTimeout(mouseTimerId);
276+
mouseTimerId = setTimeout(function(){
277+
el.style.display = 'none';
278+
}, 1000);
279+
}, 0);
280+
}
281+
282+
var touchTimerId;
283+
function onTouchMove(e) {
284+
clearTimeout(touchTimerId);
285+
touchTimerId = setTimeout(function(){
286+
var el = document.getElementById('touchmove-notify');
287+
el.style.display = 'block';
288+
clearTimeout(touchTimerId);
289+
touchTimerId = setTimeout(function(){
290+
el.style.display = 'none';
291+
}, 1000);
292+
}, 0);
293+
}
294+
295+
document.addEventListener('touchmove', onTouchMove, false);
296+
document.addEventListener('mousemove', onMouseMove, false);
219297
</script>
220298
</body>
221299
</html>

Diff for: js/utils/tap.js

+8-8
Original file line numberDiff line numberDiff line change
@@ -135,10 +135,10 @@
135135
return false;
136136
}
137137

138-
return (c.x > startCoordinates.x + HIT_RADIUS ||
139-
c.x < startCoordinates.x - HIT_RADIUS ||
140-
c.y > startCoordinates.y + HIT_RADIUS ||
141-
c.y < startCoordinates.y - HIT_RADIUS);
138+
return (c.x > startCoordinates.x + TOUCH_TOLERANCE_X ||
139+
c.x < startCoordinates.x - TOUCH_TOLERANCE_X ||
140+
c.y > startCoordinates.y + TOUCH_TOLERANCE_Y ||
141+
c.y < startCoordinates.y - TOUCH_TOLERANCE_Y);
142142
}
143143

144144
function recordCoordinates(event) {
@@ -180,7 +180,6 @@
180180
clickPreventTimerId = setTimeout(function(){
181181
var tap = isRecentTap(e);
182182
if(tap) delete tapCoordinates[tap.id];
183-
startCoordinates = {};
184183
}, REMOVE_PREVENT_DELAY);
185184
}
186185

@@ -206,10 +205,12 @@
206205
}
207206

208207
var tapCoordinates = {}; // used to remember coordinates to ignore if they happen again quickly
209-
var startCoordinates = {}; // used to remember where the coordinates of the start of the tap
208+
var startCoordinates = {}; // used to remember where the coordinates of the start of a touch
210209
var CLICK_PREVENT_DURATION = 1500; // max milliseconds ghostclicks in the same area should be prevented
211210
var REMOVE_PREVENT_DELAY = 380; // delay after a touchend/mouseup before removing the ghostclick prevent
212-
var HIT_RADIUS = 15;
211+
var HIT_RADIUS = 15; // surrounding area of a click that if a ghostclick happens it would get ignored
212+
var TOUCH_TOLERANCE_X = 4; // how much the X coordinates can be off between start/end, but still a click
213+
var TOUCH_TOLERANCE_Y = 2; // how much the Y coordinates can be off between start/end, but still a click
213214

214215
ionic.Platform.ready(function(){
215216

@@ -230,7 +231,6 @@
230231

231232
// in the case the user touched the screen, then scrolled, it shouldn't fire the click
232233
document.addEventListener('touchstart', recordStartCoordinates, false);
233-
document.addEventListener('mousedown', recordStartCoordinates, false);
234234
});
235235

236236
})(this, document, ionic);

0 commit comments

Comments
 (0)