使用iScroll4脚本在iphone浏览器中使用<select>下拉闪烁

Jit*_*yas 3 javascript css iphone mobile-safari iscroll4

请参阅页面底部的iphone http://jsbin.com/unese4/8中的此演示页面,其中有一个下拉列表打开但无法正常工作.

此问题与此问题有关iScroll 4无法使用表单<select>元素iPhone Safari和Android浏览器

s4y*_*s4y 7

实际上,您的问题与此问题有关:

使用select元素在safari上进行webkit-transform问题

当输入在iOS Safari中获得焦点时,它会检查输入是否在视图中.如果不是,Safari会强制滚动文档以及包含输入的元素,以使其可见.

iScroll使用CSS变换来移动可滚动区域,看起来Safari的行为被破坏了select- 它没有注意到变换,认为它select不在视野范围内,并且滚动其容器(#scrollable)使其可见(再次,不考虑变换),这使它脱离了视野.

这基本上是一个iOS错误,应该由受此问题影响的许多Web开发人员向Apple报告!可以在iScroll内部最有效地实施解决方法,因此我建议您向其开发人员报告该问题.

也就是说,我已经提出了一个解决方法,你可以在这个答案的底部找到.您可以通过使用iScroll实例调用它一次来使用它:

workAroundiScrollSelectPositioning(myScroll);
Run Code Online (Sandbox Code Playgroud)

现场演示为您jsbin贴在这里.当select获得焦点时触发它,并做三件事:

  1. 记住滚动位置,并告诉iScroll立即滚动到左上角(删除任何变换),并设置topleft滚动区域的CSS属性对于当前滚动位置.在视觉上,一切看起来都一样,但滚动区域现在以Safari将看到的方式定位.

  2. 阻止iScroll看到任何触摸(这很难看,但它会阻止iScroll在滚动区域应用转换时重新定位).

  3. select失去焦点时,将所有内容恢复原状(恢复原始位置并转换并停止阻止iScroll).

仍然存在元素位置可能被搞砸的情况(例如,当textarea有焦点但只是部分在视图中,并且您键入并导致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);
}
Run Code Online (Sandbox Code Playgroud)