Skip to content

Commit 8af018b

Browse files
committed
fix(scroll): Allow scrolling when touchstart target is an input, #1078
1 parent d00aaa5 commit 8af018b

File tree

3 files changed

+105
-8
lines changed

3 files changed

+105
-8
lines changed

Diff for: js/ext/angular/test/service/ionicTap.unit.js

+95
Original file line numberDiff line numberDiff line change
@@ -290,4 +290,99 @@ describe('Ionic Tap', function() {
290290
expect( ionic.tap.ignoreTapInspect(e) ).toEqual(false);
291291
});
292292

293+
it('Should not prevent scrolling', function() {
294+
var target = document.createElement('div');
295+
var e = {
296+
target: target
297+
};
298+
expect( ionic.tap.ignoreScrollStart(e) ).toEqual(false);
299+
});
300+
301+
it('Should prevent scrolling because the event has defaultedPrevented', function() {
302+
var target = document.createElement('div');
303+
var e = {
304+
target: target,
305+
defaultPrevented: true
306+
};
307+
expect( ionic.tap.ignoreScrollStart(e) ).toEqual(true);
308+
});
309+
310+
it('Should not prevent scrolling if the target was an input or textarea', function() {
311+
var target = document.createElement('input');
312+
var e = {
313+
target: target
314+
};
315+
expect( ionic.tap.ignoreScrollStart(e) ).toEqual(false);
316+
});
317+
318+
it('Should prevent scrolling if the target was an input or textarea, and the target is the same as the active element', function() {
319+
var target = document.createElement('input');
320+
ionic.tap.activeElement(target);
321+
var e = {
322+
target: target
323+
};
324+
expect( ionic.tap.ignoreScrollStart(e) ).toEqual(true);
325+
});
326+
327+
it('Should not prevent scrolling if the target isContentEditable', function() {
328+
var target = document.createElement('div');
329+
target.isContentEditable = true;
330+
var e = {
331+
target: target
332+
};
333+
expect( ionic.tap.ignoreScrollStart(e) ).toEqual(false);
334+
});
335+
336+
it('Should prevent scrolling if the target has dataset.preventScroll', function() {
337+
var target = document.createElement('div');
338+
target.setAttribute('data-prevent-scroll', 'true');
339+
var e = {
340+
target: target
341+
};
342+
expect( ionic.tap.ignoreScrollStart(e) ).toEqual(true);
343+
344+
target = document.createElement('div');
345+
target.dataset.preventScroll = true;
346+
e = {
347+
target: target
348+
};
349+
expect( ionic.tap.ignoreScrollStart(e) ).toEqual(true);
350+
351+
target = document.createElement('div');
352+
target.dataset.preventScroll = 'true';
353+
e = {
354+
target: target
355+
};
356+
expect( ionic.tap.ignoreScrollStart(e) ).toEqual(true);
357+
});
358+
359+
it('Should prevent scrolling if the browser doesnt support dataset but target has data-prevent-default attribute', function() {
360+
var target = {
361+
tagName: 'div',
362+
getAttribute: function(val) {
363+
if(val === 'data-prevent-default') {
364+
return 'true';
365+
}
366+
}
367+
}
368+
var e = {
369+
target: target
370+
};
371+
expect( ionic.tap.ignoreScrollStart(e) ).toEqual(true);
372+
});
373+
374+
it('Should prevent scrolling if the target is an object or embed', function() {
375+
var target = document.createElement('object');
376+
var e = {
377+
target: target
378+
};
379+
expect( ionic.tap.ignoreScrollStart(e) ).toEqual(true);
380+
381+
target = document.createElement('embed');
382+
e = {
383+
target: target
384+
};
385+
expect( ionic.tap.ignoreScrollStart(e) ).toEqual(true);
386+
});
387+
293388
});

Diff for: js/utils/tap.js

+8
Original file line numberDiff line numberDiff line change
@@ -263,6 +263,14 @@
263263
reset: function() {
264264
tapCoordinates = {};
265265
startCoordinates = {};
266+
},
267+
268+
ignoreScrollStart: function(e) {
269+
return (e.defaultPrevented) || // defaultPrevented has been assigned by another component handling the event
270+
(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
271+
(e.target.isContentEditable) ||
272+
(e.target.dataset ? e.target.dataset.preventScroll : e.target.getAttribute('data-prevent-default')) == 'true' || // manually set within an elements attributes
273+
(!!e.target.tagName.match(/object|embed/i)); // flash/movie/object touches should not try to scroll
266274
}
267275

268276
};

Diff for: js/views/scrollView.js

+2-8
Original file line numberDiff line numberDiff line change
@@ -616,16 +616,10 @@ ionic.views.Scroll = ionic.views.View.inherit({
616616
e.stopPropagation();
617617
});
618618

619-
function shouldIgnorePress(e) {
620-
return e.target.tagName.match(/input|textarea|select|object|embed/i) ||
621-
e.target.isContentEditable ||
622-
(e.target.dataset ? e.target.dataset.preventScroll : e.target.getAttribute('data-prevent-default') == 'true');
623-
}
624-
625619
if ('ontouchstart' in window) {
626620

627621
container.addEventListener("touchstart", function(e) {
628-
if (e.defaultPrevented || shouldIgnorePress(e)) {
622+
if ( ionic.tap.ignoreScrollStart(e) ) {
629623
return;
630624
}
631625
self.doTouchStart(e.touches, e.timeStamp);
@@ -648,7 +642,7 @@ ionic.views.Scroll = ionic.views.View.inherit({
648642
var mousedown = false;
649643

650644
container.addEventListener("mousedown", function(e) {
651-
if (e.defaultPrevented || shouldIgnorePress(e)) {
645+
if ( ionic.tap.ignoreScrollStart(e) ) {
652646
return;
653647
}
654648
self.doTouchStart([{

0 commit comments

Comments
 (0)