laviastar / iscroll-js

Automatically exported from code.google.com/p/iscroll-js
MIT License
2 stars 2 forks source link

Default scrolling not always prevented on text inputs #24

Open GoogleCodeExporter opened 9 years ago

GoogleCodeExporter commented 9 years ago
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.

Original issue reported on code.google.com by bry...@gmail.com on 24 Aug 2010 at 7:33

GoogleCodeExporter commented 9 years ago
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.

Original comment by bry...@gmail.com on 24 Aug 2010 at 9:44

GoogleCodeExporter commented 9 years ago
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.

Original comment by mat...@gmail.com on 26 Aug 2010 at 1:13

GoogleCodeExporter commented 9 years ago
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...)

Original comment by bry...@gmail.com on 26 Aug 2010 at 10:49

GoogleCodeExporter commented 9 years ago
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.

Original comment by cary.cal...@gmail.com on 1 Sep 2010 at 8:12

Attachments:

GoogleCodeExporter commented 9 years ago
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.

Original comment by m...@thomasbachem.com on 27 Apr 2011 at 2:19

GoogleCodeExporter commented 9 years ago
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.

Original comment by n...@nick-evans.com on 2 Sep 2011 at 9:09

GoogleCodeExporter commented 9 years ago
@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...

Original comment by t...@itsravenous.com on 26 Sep 2012 at 8:42