| Issue 24: | Default scrolling not always prevented on text inputs | |
| 6 people starred this issue and may be notified of changes. | Back to list |
What steps will reproduce the problem? 1. Add a text input to each list item in the simple example (<input type="text">) 2. View demo in iPhone 3. Tap & hold on a text input, then drag up or down. What is the expected output? What do you see instead? Expect the surrounding webview to remain stationary. Instead, dragging triggers both the iScroll scrolling and the default web view scrolling (i.e., I can see the browser chrome with URL bar move). This does not happen every time, but I can reproduce about 25% of the time. What version of the product are you using? On what operating system? iScroll 3.5, 3.6. iPhone 3GS, iPhone simulator, & iPhone 4 sim. Please provide any additional information below. The symptom occurs before touchend (when the keyboard input appears). The touchmove event does not appear to fire in when this symptom is visible.
Aug 24, 2010
#1
bry...@gmail.com
Aug 26, 2010
I'm afraid there's very little we can do about it. A solution could be to disable the inputs and re-enable them when needed.
Status:
Accepted
Owner: matt3o
Aug 26, 2010
I'm not sure disabling the inputs would work, at least in my case. Not being able to preventDefault on touchstart & touchmove seems to be a non-starter there. Another idea would be to place hidden spans on top of the form inputs to prevent the dragging from happening, and programatically trigger focus on the covered input when a click event fires on the span. I wasn't able to get the keyboard to appear after a little trying, though. (I'm sure that's beyond the scope of iscroll; just throwing out ideas...)
Sep 1, 2010
I've had some success, on iPhone, with putting an invisible div in front of text inputs to prevent this issue. This is the approach described in comment 3. I also ran into the mentioned problem of not being able to programmatically trigger focus (by calling focus()) on the input. I got around it by: 1. NOT calling preventDefault() on the touchstart event. 2. Setting "display: none" on the invisible div when it's clicked, and then calling focus() on the text input. Then, when the text input gets the blur event, setting the display property of the div back to whatever it was originally. I've attached my modified version of iscroll so that you can see one way to avoid calling preventDefault on touchstart without side effects. It's based on iscroll version 3.6. There are other (probably better) ways to do this mentioned in issue 17. If you can't get this working from the instructions I can throw together an example.
Apr 26, 2011
I think I've found a great workaround for this issue using the "pointer-events" CSS property:
function setTextareaPointerEvents(value) {
var nodes = document.getElementsByTagName('textarea');
for(var i = 0; i < nodes.length; i++) {
nodes[i].style.pointerEvents = value;
}
}
document.addEventListener('DOMContentLoaded', function() {
setTextareaPointerEvents('none');
});
document.addEventListener('touchstart', function() {
setTextareaPointerEvents('auto');
});
document.addEventListener('touchmove', function() {
e.preventDefault();
setTextareaPointerEvents('none');
});
document.addEventListener('touchend', function() {
setTimeout(function() {
setTextareaPointerEvents('none');
}, 0);
});
This will make Mobile Safari (others not tested so far) ignore the textareas for scrolling but allows to set focus etc. as usual.
Sep 2, 2011
Thomas's comment almost worked for me, but not quite. In the end I resorted to using the label element for each input as a "mask" over the top of the input, then used click/focusout handlers to manage the z-position of the label like this,
$('.form-type-textfield label, .form-type-textarea label').live('click', function(){
$(this).css('z-index', '1');
$(this).parents('.form-item').find('textarea').focus();
$(this).parents('.form-item').find('input').focus();
});
$('.form-type-textfield input, .form-type-textarea textarea').live('focusout', function(){
$(this).parents('.form-item').find('label').css('z-index', '99');
});
Hope this helps someone.
Sep 26, 2012
@Thomas - this works for me, but the tap has to be slightly longer than usual - i.e. quick tap won't focus the input (as presumably the pointer events = auto call doesn't have time to fire before the touchend event). This makes for a frustrating user experience, but seems to be the only solution - I assume Nick's doesn't bring up the iOS keyboard as it's a programmatic focus, not user initiated...
Jul 17, 2015
Try my solution. This should be the best: http://stackoverflow.com/a/31472878/931908 |