Skip to content

Commit

Permalink
fix(scroll): Allow scrolling when touchstart target is an input, #1078
Browse files Browse the repository at this point in the history
  • Loading branch information
adamdbradley committed Apr 8, 2014
1 parent d00aaa5 commit 8af018b
Show file tree
Hide file tree
Showing 3 changed files with 105 additions and 8 deletions.
95 changes: 95 additions & 0 deletions js/ext/angular/test/service/ionicTap.unit.js
Original file line number Diff line number Diff line change
Expand Up @@ -290,4 +290,99 @@ describe('Ionic Tap', function() {
expect( ionic.tap.ignoreTapInspect(e) ).toEqual(false);
});

it('Should not prevent scrolling', function() {
var target = document.createElement('div');
var e = {
target: target
};
expect( ionic.tap.ignoreScrollStart(e) ).toEqual(false);
});

it('Should prevent scrolling because the event has defaultedPrevented', function() {
var target = document.createElement('div');
var e = {
target: target,
defaultPrevented: true
};
expect( ionic.tap.ignoreScrollStart(e) ).toEqual(true);
});

it('Should not prevent scrolling if the target was an input or textarea', function() {
var target = document.createElement('input');
var e = {
target: target
};
expect( ionic.tap.ignoreScrollStart(e) ).toEqual(false);
});

it('Should prevent scrolling if the target was an input or textarea, and the target is the same as the active element', function() {
var target = document.createElement('input');
ionic.tap.activeElement(target);
var e = {
target: target
};
expect( ionic.tap.ignoreScrollStart(e) ).toEqual(true);
});

it('Should not prevent scrolling if the target isContentEditable', function() {
var target = document.createElement('div');
target.isContentEditable = true;
var e = {
target: target
};
expect( ionic.tap.ignoreScrollStart(e) ).toEqual(false);
});

it('Should prevent scrolling if the target has dataset.preventScroll', function() {
var target = document.createElement('div');
target.setAttribute('data-prevent-scroll', 'true');
var e = {
target: target
};
expect( ionic.tap.ignoreScrollStart(e) ).toEqual(true);

target = document.createElement('div');
target.dataset.preventScroll = true;
e = {
target: target
};
expect( ionic.tap.ignoreScrollStart(e) ).toEqual(true);

target = document.createElement('div');
target.dataset.preventScroll = 'true';
e = {
target: target
};
expect( ionic.tap.ignoreScrollStart(e) ).toEqual(true);
});

it('Should prevent scrolling if the browser doesnt support dataset but target has data-prevent-default attribute', function() {
var target = {
tagName: 'div',
getAttribute: function(val) {
if(val === 'data-prevent-default') {
return 'true';
}
}
}
var e = {
target: target
};
expect( ionic.tap.ignoreScrollStart(e) ).toEqual(true);
});

it('Should prevent scrolling if the target is an object or embed', function() {
var target = document.createElement('object');
var e = {
target: target
};
expect( ionic.tap.ignoreScrollStart(e) ).toEqual(true);

target = document.createElement('embed');
e = {
target: target
};
expect( ionic.tap.ignoreScrollStart(e) ).toEqual(true);
});

});
8 changes: 8 additions & 0 deletions js/utils/tap.js
Original file line number Diff line number Diff line change
Expand Up @@ -263,6 +263,14 @@
reset: function() {
tapCoordinates = {};
startCoordinates = {};
},

ignoreScrollStart: function(e) {
return (e.defaultPrevented) || // defaultPrevented has been assigned by another component handling the event
(e.target.tagName.match(/input|textarea/i) && ionic.tap.activeElement() === e.target) || // target is the active element, so its a second tap to select input text
(e.target.isContentEditable) ||
(e.target.dataset ? e.target.dataset.preventScroll : e.target.getAttribute('data-prevent-default')) == 'true' || // manually set within an elements attributes
(!!e.target.tagName.match(/object|embed/i)); // flash/movie/object touches should not try to scroll
}

};
Expand Down
10 changes: 2 additions & 8 deletions js/views/scrollView.js
Original file line number Diff line number Diff line change
Expand Up @@ -616,16 +616,10 @@ ionic.views.Scroll = ionic.views.View.inherit({
e.stopPropagation();
});

function shouldIgnorePress(e) {
return e.target.tagName.match(/input|textarea|select|object|embed/i) ||
e.target.isContentEditable ||
(e.target.dataset ? e.target.dataset.preventScroll : e.target.getAttribute('data-prevent-default') == 'true');
}

if ('ontouchstart' in window) {

container.addEventListener("touchstart", function(e) {
if (e.defaultPrevented || shouldIgnorePress(e)) {
if ( ionic.tap.ignoreScrollStart(e) ) {
return;
}
self.doTouchStart(e.touches, e.timeStamp);
Expand All @@ -648,7 +642,7 @@ ionic.views.Scroll = ionic.views.View.inherit({
var mousedown = false;

container.addEventListener("mousedown", function(e) {
if (e.defaultPrevented || shouldIgnorePress(e)) {
if ( ionic.tap.ignoreScrollStart(e) ) {
return;
}
self.doTouchStart([{
Expand Down

0 comments on commit 8af018b

Please sign in to comment.