3 回答
实际上,您的问题与此问题有关:
当输入在 iOS Safari 中获得焦点时,它会检查输入是否在视图中。如果不是,Safari 会强制滚动文档和包含输入的元素,以使其可见。
iScroll 使用 CSS 变换来移动可滚动区域,看起来 Safari 对selects 的行为已被破坏——它没有注意到变换,认为select不在视野中,并滚动其容器 ( #scrollable) 以使其可见 (再一次,不考虑转换),这使它消失了。
这基本上是一个 iOS 错误,应该由受此问题影响的尽可能多的 Web 开发人员报告给 Apple !解决方法可以在 iScroll 中最有效地实现,因此我鼓励您将问题报告给它的开发人员。
也就是说,我想出了一个解决方法,您可以在这个答案的底部找到它。您可以通过 iScroll 实例调用一次来使用它:
workAroundiScrollSelectPositioning(myScroll);
现场演示在您的 jsbin 粘贴处。它在获得焦点时触发select,并执行三件事:
记住滚动位置,并告诉 iScroll 立即滚动到左上角(删除任何变换),并将滚动区域的
top和leftCSS 属性设置为当前滚动位置。从视觉上看,一切看起来都一样,但滚动区域现在以 Safari 可以看到的方式定位。阻止 iScroll 看到任何触摸(这很丑陋,但它会阻止 iScroll 在我们重新定位滚动区域时对其应用变换)。
当
select失去焦点时,将一切恢复原状(恢复原始位置并变换并停止阻塞 iScroll)。
仍然存在元素位置可能被搞砸的情况(例如,当 atextarea具有焦点但仅部分显示在视图中,并且您键入并导致 Safari 尝试将其其余部分显示在视图中时),但这些最好在 iScroll 中修复.
function workAroundiScrollSelectPositioning(iscroll){
iscroll.scroller.addEventListener('focusin', function(e){
if (e.target.tagName === 'SELECT') {
var touchEvent = 'ontouchstart' in window ? 'touchmove' : 'mousemove',
touchListener = {
handleEvent: function(e){
e.stopPropagation();
e.stopImmediatePropagation();
}
},
blurListener = {
oldX: iscroll.x,
oldY: iscroll.y,
handleEvent: function(e){
iscroll.scroller.style.top = '';
iscroll.scroller.style.left = '';
iscroll.scrollTo(this.oldX, this.oldY, 0);
e.target.removeEventListener('blur', blurListener, false);
iscroll.scroller.removeEventListener(touchEvent, touchListener, true);
}
};
iscroll.scroller.style.top = iscroll.y + 'px';
iscroll.scroller.style.left = iscroll.x + 'px';
iscroll.scrollTo(0, 0, 0);
e.target.addEventListener('blur', blurListener, false);
iscroll.scroller.addEventListener(touchEvent, touchListener, true);
}
}, false);
}
您可以在该位置使用自定义表格视图,假设您想在用户单击文本字段时显示下拉列表。因此,当用户在文本字段上单击时,委托方法会被调用 TextFieldBeginEditing 并在其中创建一个小表格视图。看起来像一个下拉列表...
这是对我有用的修改后的函数 workAroundiScrollSelectPositioning。
function workAroundiScrollSelectPositioning(iscroll){
var touchEvent = 'ontouchstart' in window ? 'touchstart' : 'mousemove',
oldX, oldY;
iscroll.scroller.addEventListener('focusin', function(e){
if (e.target.tagName === 'SELECT') {
var blurListener = {
oldX: oldX,
oldY: oldY,
handleEvent: function(e){
iscroll.scroller.style['margin-top'] = '';
iscroll.scroller.style.left = '';
iscroll.scrollTo(oldX, oldY, 0);
e.target.removeEventListener('blur', blurListener, false);
}
};
iscroll.scroller.style['margin-top'] = oldY + 'px';
iscroll.scroller.style.left = oldX + 'px';
iscroll.scrollTo(0, 0, 0);
e.target.addEventListener('blur', blurListener, false);
}
}, false);
iscroll.scroller.addEventListener(touchEvent, {
handleEvent: function(e){
if (e.target.tagName === 'SELECT') {
oldX = iscroll.x,
oldY = iscroll.y;
e.stopPropagation();
e.stopImmediatePropagation();
}
}
}, true);}