iScroll 4不在输入元素上滚动

时间:2012-10-11 22:47:25

标签: javascript android ios iscroll

我正在构建一个针对Android 2.2 +,Blackberry 9+和iOS 4+的移动应用。在我们的堆栈中,我们使用Phonegap,jQuery和iScroll(以及其他)。

我们的一个应用程序屏幕看起来像这样(匿名文本编辑) - 在iOS 5模拟器的Safari中运行。

App Screenshot

正如您所看到的,这是一个典型的输入屏幕,带有固定的标题,多个块级表单元素可以扩展设备屏幕,减少填充。

正如我所提到的,我们的应用程序使用iScroll。我们使用以下代码在此页面上对其进行初始化(取自iScroll'表单'示例)。

// ...

window.scroller = new iScroll(id, {
    useTransform: false,
    onBeforeScrollStart: function(e) {
        var target = e.target;
        while (target.nodeType != 1) target = target.parentNode;
        if(target.tagName != 'select'
            && target.tagName != 'input'
            && target.tagName != 'textarea') {
            e.preventDefault();
        }
    }
});

// Disable touch scrolling (Req'd for iScroll)
window.document.addEventListener('touchmove', function(e) {
    e.preventDefault();
}, false);

// ...

在这个屏幕上,我注意到当用户触摸背景的任何部分时内容滚动得很好,但是当你通过触摸其中一个输入元素开始滚动手势(向上或向下滑动)时内容不会滚动。你可以理解这基本上使这个屏幕无法使用,因此我寻找修复。

我已经在iScroll中找到了罪魁祸首;

if (nodeName == "TEXTAREA" || nodeName == "INPUT" || nodeName == "SELECT" ) return; 

(iscroll.js中为179),open issue for this bug已声明已修复,另有pull request that claims to fix it,但该错误的作者似乎有错误的行号,阻止我尝试修复,并且提到的拉取请求对我不起作用(在iOS 5.1,Android 4.0.4上测试)。

我的问题 - 是否有某种方法允许用户在触摸输入元素时滚动(使用iScroll)?如果没有,iScroll在这种情况下完全没用。目前,我正在寻找

  • 使用声称与iScroll具有相同功能的Overthrow shim - 但由于various issues with Android,这不是一个很好的选择 - 我们的主要平台之一。
  • 取消iScroll并丢失我的固定标题。

2012年 - 我们还没有办法在移动浏览器上做到这一点吗?!?

5 个答案:

答案 0 :(得分:1)

我意识到这张票有点陈旧,但我遇到了同样的问题。 我在iOS上使用iScroll v4。

我在设置iScroll对象时找到了这个解决方案(在某处)添加以下内容:

        myScroll = new iScroll(id, {
            useTransform: false,
            onBeforeScrollStart: function (e) {
                var target = e.target;
                while (target.nodeType != 1) target = target.parentNode;

                if (target.tagName != 'SELECT' && target.tagName != 'INPUT' && target.tagName != 'TEXTAREA') {
                    e.preventDefault();
                }
            }
        });

但是我发现此代码有两个问题:

a)useTransform打破了我自动隐藏单选按钮的表单布局,以便按照此页面显示“漂亮图形”(http://webdesign.tutsplus.com/tutorials/htmlcss-tutorials/quick-tip-easy-css3-checkboxes-and-radio-buttons/)。我不知道为什么会破坏这种布局,可能只是部分关系,我可以用另一种方式修复但是...我注释掉了useTransform并修复了它...

b)对于拉起虚拟键盘的输入,在隐藏键盘后,页面保持“向上滚动”(屏幕和页脚从底部向上约1/4),所以我添加了“onBlur”事件到“重新滚动”窗口,这似乎有效......这是我的最终解决方案。

    myScroll = new iScroll(id, {
        //useTransform: false,
        onBeforeScrollStart: function (e) {
            var target = e.target;
            while (target.nodeType != 1) target = target.parentNode;

            if (target.tagName != 'SELECT' && target.tagName != 'INPUT' && target.tagName != 'TEXTAREA') {
                e.preventDefault();
            } else {
                $(target).bind('blur', function(){
                    window.scrollTo(0,0);
                    myScroll.refresh();
                });
            }
        }
    });

希望这有帮助!!!

答案 1 :(得分:0)

删除preventDefault():

window.scroller = new iScroll(id, {
    useTransform: false,
    onBeforeScrollStart: function(e) {
        var target = e.target;
        while (target.nodeType != 1) target = target.parentNode;
        if(target.tagName != 'select'
            && target.tagName != 'input'
            && target.tagName != 'textarea') {

            // remove this code right here:
            e.preventDefault();
        }
    }
});

答案 2 :(得分:0)

我遇到了完全相同的问题,并在设置iScroll时使用了以下内容:

var ISCROLL_MOVE;

var ISCROLL_MOVE_LIMIT=10;

// ... functions to include when you set up your iScroll
onScrollStart: function(e) {
                ISCROLL_MOVE=0;
            },
            onScrollMove: function(e) {
                ISCROLL_MOVE_LIMIT++;
            }

然后,当您在iScroll中有任何表单元素时,例如:

var selectField = document.getElementById('mySelectField');

selectField.addEventListener('touchend' /*'mousedown'*/, function(e) {

        if (SCROLL_MOVE<SCROLL_MOVE_LIMIT)
            this.focus();

    }, false);

注意操作是在触摸结束事件上,它允许在用户触摸表单元素时滚动iScroll页面 - 基本上它测量用户正在进行的滚动量(或不滚动)(SCROLL_MOVE的数量) )。如果它超过10(SCROLL_MOVE_LIMIT对我来说似乎是一个很好的数字)那么该字段将不会抓住焦点,否则它会。

如果您需要更多详细信息,请与我们联系。

答案 3 :(得分:0)

我在这里回答一下,没有java-script和iscroll hacks

https://stackoverflow.com/a/17390516/1458628

答案 4 :(得分:0)

我完美地解决了它。如果您使用的是iscroll.js,则可以通过编辑iscroll.js文件轻松解决。

我编辑了_move(e)函数定义。 您将在_move(e)的函数定义中看到以下代码:     在这里输入代码

Dockerfile

//在else条件中包含上面的代码。 if条件应该在下面:

that.moved = true;
   that._pos(newX, newY);
   that.dirX = deltaX > 0 ? -1 : deltaX < 0 ? 1 : 0;
that.dirY = deltaY > 0 ? -1 : deltaY < 0 ? 1 : 0;
if (timestamp - that.startTime > 300) {
   that.startTime = timestamp;
   that.startX = that.x;
   that.startY = that.y;
}
if (that.options.onScrollMove) that.options.onScrollMove.call(that, e);

//在IPad中测试。对我来说很好。