我正在构建一个针对Android 2.2 +,Blackberry 9+和iOS 4+的移动应用。在我们的堆栈中,我们使用Phonegap,jQuery和iScroll(以及其他)。
我们的一个应用程序屏幕看起来像这样(匿名文本编辑) - 在iOS 5模拟器的Safari中运行。
正如您所看到的,这是一个典型的输入屏幕,带有固定的标题,多个块级表单元素可以扩展设备屏幕,减少填充。
正如我所提到的,我们的应用程序使用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在这种情况下完全没用。目前,我正在寻找
2012年 - 我们还没有办法在移动浏览器上做到这一点吗?!?
答案 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
答案 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中测试。对我来说很好。