2

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

我们的一个应用程序屏幕如下所示(为匿名而编辑的文本)- 在 iOS 5 模拟器的 Safari 中运行。

应用截图

如您所见,这是一个典型的输入屏幕,具有固定的标题,多个块级表单元素延伸到设备屏幕的整个区域,更少的填充。

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

// ...

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),此错误的一个未解决问题,声称修复,以及一个声称修复它的拉取请求,但是错误的作者似乎有不正确的行号,阻止我尝试修复,并且提到的拉取请求对我不起作用(在 iOS 5.1、Android 4.0.4 上测试)。

我的问题 - 有没有办法让用户在触摸输入元素时滚动(使用 iScroll)?如果没有,iScroll 在这种情况下完全没用。目前,我正在看

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

4

5 回答 5

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();
                }
            }
        });

但是,我发现此代码存在 2 个问题:

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();
                });
            }
        }
    });

希望这可以帮助!!!

于 2013-04-21T20:49:55.370 回答
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();
        }
    }
});
于 2012-10-11T23:00:52.063 回答
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 对我来说似乎是一个不错的数字),那么该字段将不会抓住焦点,否则会。

如果您需要更多详细信息,请告诉我。

于 2012-11-13T11:48:39.113 回答
0

我会在这里回答它,没有 java-script 和 iscroll hacks

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

于 2013-06-30T12:51:38.260 回答
0

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

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

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);

//把上面的代码放在else条件中。并且 if 条件应该如下:

enter code here
if (e.srcElement.localName == 'textarea') {
  var scrollHeight = e.srcElement.scrollHeight;
  var scrollTop = e.srcElement.scrollTop;
  if (scrollTop >= 0 && screenTop <= scrollHeight) {
       that.dirY = that.dirY * 5;
       e.srcElement.scrollTop = scrollTop + that.dirY;
  }
}

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

于 2015-12-18T07:04:18.967 回答