Issue 24: Default scrolling not always prevented on text inputs
Status:  Accepted
Owner:
Reported by bry...@gmail.com, Aug 24, 2010
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
Text inputs don't seem to respond to touchstart nor touchend events, with or without iScroll involved. In other words, I don't seem to be able to prevent the default dragging if it happens on a form element at all. This doesn't appear to be an iScroll bug per se, but perhaps there's a workaround.
Aug 26, 2010
Project Member #2 mat...@gmail.com
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
#3 bry...@gmail.com
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
#4 cary.cal...@gmail.com
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.
iscroll.js
19.9 KB   View   Download
Apr 26, 2011
#5 m...@thomasbachem.com
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
#6 n...@nick-evans.com
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
#7 t...@itsravenous.com
@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
#8 lanshunf...@gmail.com
Try my solution. This should be the best:

http://stackoverflow.com/a/31472878/931908