mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2026-03-13 10:22:08 +08:00
fix(tap): Do not preventDefault after input focus, #1068
This commit is contained in:
@@ -23,34 +23,6 @@ describe('Ionic Tap', function() {
|
||||
expect(targetEle.isFocused).toEqual(true);
|
||||
});
|
||||
|
||||
it('Should preventDefault on an input', function() {
|
||||
var targetEle = {
|
||||
dispatchEvent: function() {},
|
||||
focus: function() {}
|
||||
};
|
||||
|
||||
ionic.tap.setTouchStart({ clientX: 100, clientY: 100 });
|
||||
var e = {
|
||||
clientX: 100, clientY: 100,
|
||||
preventDefault: function() { this.preventedDefault = true }
|
||||
};
|
||||
|
||||
targetEle.tagName = 'INPUT';
|
||||
ionic.tap.simulateClick(targetEle, e);
|
||||
expect(e.preventedDefault).toEqual(true);
|
||||
e.preventedDefault = false;
|
||||
|
||||
targetEle.tagName = 'TEXTAREA';
|
||||
ionic.tap.simulateClick(targetEle, e);
|
||||
expect(e.preventedDefault).toEqual(true);
|
||||
e.preventedDefault = false;
|
||||
|
||||
targetEle.tagName = 'DIV';
|
||||
ionic.tap.simulateClick(targetEle, e);
|
||||
expect(e.preventedDefault).toEqual(false);
|
||||
e.preventedDefault = false;
|
||||
});
|
||||
|
||||
it('Should setTouchStart and hasTouchScrolled true if >= touch tolerance', function() {
|
||||
ionic.tap.setTouchStart({ clientX: 100, clientY: 100 });
|
||||
|
||||
@@ -183,13 +155,6 @@ describe('Ionic Tap', function() {
|
||||
expect( ionic.tap.ignoreSimulateClick(targetEle) ).toEqual(true);
|
||||
});
|
||||
|
||||
it('Should ignoreSimulateClick for input[file] elements', function() {
|
||||
// Reported that on Android input[file] does not open using the tap
|
||||
var targetEle = document.createElement('input');
|
||||
targetEle.type = 'file';
|
||||
expect( ionic.tap.ignoreSimulateClick(targetEle) ).toEqual(true);
|
||||
});
|
||||
|
||||
it('Should ignoreSimulateClick for input[range] elements', function() {
|
||||
// Range and tap do not agree, probably because it doesn't have a delay to begin with
|
||||
var targetEle = document.createElement('input');
|
||||
@@ -227,4 +192,56 @@ describe('Ionic Tap', function() {
|
||||
expect(ionic.tap.isTapElement('P')).toEqual(false);
|
||||
});
|
||||
|
||||
it('Should focus input', function() {
|
||||
var ele = {
|
||||
tagName: 'input',
|
||||
focus: function(){ this.hasFocus=true; }
|
||||
}
|
||||
ionic.tap.handleFocus(ele);
|
||||
expect( ele.hasFocus ).toEqual(true);
|
||||
});
|
||||
|
||||
it('Should focus textarea', function() {
|
||||
var ele = {
|
||||
tagName: 'textarea',
|
||||
focus: function(){ this.hasFocus=true; }
|
||||
}
|
||||
ionic.tap.handleFocus(ele);
|
||||
expect( ele.hasFocus ).toEqual(true);
|
||||
});
|
||||
|
||||
it('Should focus select', function() {
|
||||
var ele = {
|
||||
tagName: 'select',
|
||||
focus: function(){ this.hasFocus=true; }
|
||||
}
|
||||
ionic.tap.handleFocus(ele);
|
||||
expect( ele.hasFocus ).toEqual(true);
|
||||
});
|
||||
|
||||
it('Should not focus on common elements', function() {
|
||||
var tags = ['div', 'span', 'i', 'body', 'section', 'article', 'aside', 'li', 'p', 'header', 'button', 'ion-content'];
|
||||
for(var x=0; x<tags.length; x++) {
|
||||
var ele = {
|
||||
tagName: tags[x],
|
||||
focus: function(){ this.hasFocus=true; }
|
||||
}
|
||||
ionic.tap.handleFocus(ele);
|
||||
expect( ele.hasFocus ).toBeUndefined();
|
||||
}
|
||||
});
|
||||
|
||||
it('Should not focus on an input that already has focus', function() {
|
||||
var ele = {
|
||||
tagName: 'input',
|
||||
focus: function(){ this.hasFocus=true; }
|
||||
}
|
||||
ionic.tap.handleFocus(ele);
|
||||
expect( ele.hasFocus ).toEqual(true);
|
||||
|
||||
ele.focus = function(){ this.hasSecondFocus=true }
|
||||
ionic.tap.handleFocus(ele);
|
||||
expect( ele.hasSecondFocus ).toBeUndefined();
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
var startCoordinates = {}; // used to remember where the coordinates of the start of a touch
|
||||
var clickPreventTimerId;
|
||||
var _hasTouchScrolled = false; // if the touchmove already exceeded the touchmove tolerance
|
||||
var _activeElement; // the element which has focus
|
||||
|
||||
|
||||
ionic.tap = {
|
||||
@@ -74,15 +75,8 @@
|
||||
|
||||
ele.dispatchEvent(clickEvent);
|
||||
|
||||
if( ele.tagName.match(/input|textarea/i) ) {
|
||||
ele.focus();
|
||||
e.preventDefault();
|
||||
} else if( ele.tagName == 'SELECT' ) {
|
||||
// select simulateClick should not preventDefault or else no options dialog
|
||||
ele.focus();
|
||||
} else {
|
||||
ionic.tap.blurActive();
|
||||
}
|
||||
// if it's an input, focus in on the target, otherwise blur
|
||||
ionic.tap.handleFocus(ele);
|
||||
|
||||
// remember the coordinates of this tap so if it happens again we can ignore it
|
||||
// but only if the coordinates are not already being actively disabled
|
||||
@@ -98,7 +92,20 @@
|
||||
},
|
||||
|
||||
ignoreSimulateClick: function(ele) {
|
||||
return ele.disabled || ele.type === 'file' || ele.type === 'range';
|
||||
return ele.disabled || ele.type === 'range';
|
||||
},
|
||||
|
||||
handleFocus: function(ele) {
|
||||
if(ionic.tap.activeElement() !== ele) {
|
||||
// only set the focus if it doesn't already have it
|
||||
if( ele.tagName.match(/input|textarea|select/i) ) {
|
||||
ionic.tap.activeElement(ele);
|
||||
ele.focus();
|
||||
} else {
|
||||
ionic.tap.activeElement(null);
|
||||
ionic.tap.blurActive();
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
preventGhostClick: function(e) {
|
||||
@@ -217,16 +224,22 @@
|
||||
},
|
||||
|
||||
blurActive: function() {
|
||||
var ele = document.activeElement;
|
||||
if(ele && (ele.tagName === "INPUT" ||
|
||||
ele.tagName === "TEXTAREA")) {
|
||||
// using a timeout to prevent funky scrolling while a keyboard hides
|
||||
var ele = ionic.tap.activeElement();
|
||||
if(ele && ele.tagName.match(/input|textarea|select/i) ) {
|
||||
setTimeout(function(){
|
||||
ele.blur();
|
||||
ionic.tap.activeElement(null);
|
||||
}, 400);
|
||||
}
|
||||
},
|
||||
|
||||
activeElement: function(ele) {
|
||||
if(arguments.length) {
|
||||
_activeElement = ele;
|
||||
}
|
||||
return _activeElement || document.activeElement;
|
||||
},
|
||||
|
||||
setTouchStart: function(e) {
|
||||
_hasTouchScrolled = false;
|
||||
startCoordinates = ionic.tap.getCoordinates(e);
|
||||
|
||||
Reference in New Issue
Block a user