mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2026-03-13 10:22:08 +08:00
fix(tap): Deactivate elements during scroll at the same time click is ignored, #997
Previously I disabled the activation class immediately on a touchmove, where as the click will still work if you touchstart and touchend within a few pixels of each other. So visually it may have looked like the click shouldn't have worked. I just updated it so the use the same numbers. For example, if you hold down an item and move just 5 pixels, the item will stay active (before it wouldn't have), and the click will fire. But at the same time, if you hold down an item, and move a larger distance, once it realizes that it went farther than 6 pixels it'll not allow a click to happen, AND it'll not show the item as being active.
This commit is contained in:
@@ -267,11 +267,14 @@
|
||||
});
|
||||
|
||||
var mouseTimerId;
|
||||
var mouseMoveCount = 0;
|
||||
function onMouseMove(e) {
|
||||
clearTimeout(mouseTimerId);
|
||||
mouseTimerId = setTimeout(function(){
|
||||
var el = document.getElementById('mousemove-notify');
|
||||
el.style.display = 'block';
|
||||
mouseMoveCount++;
|
||||
el.innerText = 'Mouse Move! ' + mouseMoveCount;
|
||||
clearTimeout(mouseTimerId);
|
||||
mouseTimerId = setTimeout(function(){
|
||||
el.style.display = 'none';
|
||||
@@ -280,11 +283,14 @@
|
||||
}
|
||||
|
||||
var touchTimerId;
|
||||
var touchMoveCount = 0;
|
||||
function onTouchMove(e) {
|
||||
clearTimeout(touchTimerId);
|
||||
touchTimerId = setTimeout(function(){
|
||||
var el = document.getElementById('touchmove-notify');
|
||||
el.style.display = 'block';
|
||||
touchMoveCount++;
|
||||
el.innerText = 'Touch Move! ' + touchMoveCount;
|
||||
clearTimeout(touchTimerId);
|
||||
touchTimerId = setTimeout(function(){
|
||||
el.style.display = 'none';
|
||||
|
||||
@@ -71,16 +71,16 @@ describe('Ionic Tap', function() {
|
||||
it('Should setStart and hasScrolled true if >= touch tolerance', function() {
|
||||
ionic.tap.setStart({ clientX: 100, clientY: 100 });
|
||||
|
||||
var s = ionic.tap.hasScrolled({ clientX: 105, clientY: 100 });
|
||||
var s = ionic.tap.hasScrolled({ clientX: 111, clientY: 100 });
|
||||
expect(s).toEqual(true);
|
||||
|
||||
s = ionic.tap.hasScrolled({ clientX: 95, clientY: 100 });
|
||||
s = ionic.tap.hasScrolled({ clientX: 89, clientY: 100 });
|
||||
expect(s).toEqual(true);
|
||||
|
||||
s = ionic.tap.hasScrolled({ clientX: 100, clientY: 103 });
|
||||
s = ionic.tap.hasScrolled({ clientX: 100, clientY: 107 });
|
||||
expect(s).toEqual(true);
|
||||
|
||||
s = ionic.tap.hasScrolled({ clientX: 100, clientY: 97 });
|
||||
s = ionic.tap.hasScrolled({ clientX: 100, clientY: 93 });
|
||||
expect(s).toEqual(true);
|
||||
|
||||
s = ionic.tap.hasScrolled({ clientX: 100, clientY: 200 });
|
||||
|
||||
@@ -5,10 +5,13 @@
|
||||
var activeElements = {}; // elements that are currently active
|
||||
var keyId = 0; // a counter for unique keys for the above ojects
|
||||
var ACTIVATED_CLASS = 'activated';
|
||||
var touchMoveClearTimer;
|
||||
|
||||
ionic.activator = {
|
||||
|
||||
start: function(e) {
|
||||
clearTimeout(touchMoveClearTimer);
|
||||
|
||||
// when an element is touched/clicked, it climbs up a few
|
||||
// parents to see if it is an .item or .button element
|
||||
ionic.requestAnimationFrame(function(){
|
||||
@@ -39,7 +42,9 @@
|
||||
// add listeners to clear all queued/active elements onMove
|
||||
if(e.type === 'touchstart') {
|
||||
document.body.removeEventListener('mousedown', ionic.activator.start);
|
||||
document.body.addEventListener('touchmove', clear, false);
|
||||
touchMoveClearTimer = setTimeout(function(){
|
||||
document.body.addEventListener('touchmove', onTouchMove, false);
|
||||
}, 85);
|
||||
setTimeout(activateElements, 85);
|
||||
} else {
|
||||
document.body.addEventListener('mousemove', clear, false);
|
||||
@@ -73,12 +78,20 @@
|
||||
}
|
||||
}
|
||||
|
||||
function onTouchMove(e) {
|
||||
if( ionic.tap.hasScrolled(e) ) {
|
||||
clear();
|
||||
}
|
||||
}
|
||||
|
||||
function onEnd(e) {
|
||||
// clear out any active/queued elements after XX milliseconds
|
||||
setTimeout(clear, 200);
|
||||
}
|
||||
|
||||
function clear() {
|
||||
clearTimeout(touchMoveClearTimer);
|
||||
|
||||
// clear out any elements that are queued to be set to active
|
||||
queueElements = {};
|
||||
|
||||
|
||||
@@ -5,8 +5,8 @@
|
||||
var REMOVE_PREVENT_DELAY = 380; // delay after a touchend/mouseup before removing the ghostclick prevent
|
||||
var REMOVE_PREVENT_DELAY_GRADE_C = 800; // same as REMOVE_PREVENT_DELAY, but for grade c devices
|
||||
var HIT_RADIUS = 15; // surrounding area of a click that if a ghostclick happens it would get ignored
|
||||
var TOUCH_TOLERANCE_X = 4; // how much the X coordinates can be off between start/end, but still a click
|
||||
var TOUCH_TOLERANCE_Y = 2; // how much the Y coordinates can be off between start/end, but still a click
|
||||
var TOUCH_TOLERANCE_X = 10; // how much the X coordinates can be off between start/end, but still a click
|
||||
var TOUCH_TOLERANCE_Y = 6; // how much the Y coordinates can be off between start/end, but still a click
|
||||
var tapCoordinates = {}; // used to remember coordinates to ignore if they happen again quickly
|
||||
var startCoordinates = {}; // used to remember where the coordinates of the start of a touch
|
||||
var clickPreventTimerId;
|
||||
@@ -110,11 +110,11 @@
|
||||
|
||||
} else if(ionic.tap.hasScrolled(e)) {
|
||||
// this click's coordinates are different than its touchstart/mousedown, must have been scrolling
|
||||
console.debug('preventGhostClick', 'hasScrolled, startCoordinates, x:' + startCoordinates.x + ' y:' + startCoordinates.y);
|
||||
console.debug('preventGhostClick', 'hasScrolled');
|
||||
}
|
||||
|
||||
var c = ionic.tap.getCoordinates(e);
|
||||
return 'click at x:' + c.x + ', y:' + c.y;
|
||||
return 'click(' + c.x + ',' + c.y + '), start(' + startCoordinates.x + ',' + startCoordinates.y + ')';
|
||||
})());
|
||||
|
||||
|
||||
@@ -153,6 +153,7 @@
|
||||
return false;
|
||||
}
|
||||
|
||||
// the allowed distance between touchstart/mousedown and
|
||||
return (c.x > startCoordinates.x + TOUCH_TOLERANCE_X ||
|
||||
c.x < startCoordinates.x - TOUCH_TOLERANCE_X ||
|
||||
c.y > startCoordinates.y + TOUCH_TOLERANCE_Y ||
|
||||
|
||||
Reference in New Issue
Block a user