简体   繁体   English

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

[英]<select> drop down flashing on focus in iphone browser with iScroll4 script

See this demo page in iphone http://jsbin.com/unese4/8 at the bottom of the page there is one dropdown which opens but doesn't work properly. 请参阅页面底部的iphone http://jsbin.com/unese4/8中的此演示页面,其中有一个下拉列表打开但无法正常工作。

This question is related to this question iScroll 4 not working with form <select> element iPhone Safari and Android browser 此问题与此问题有关iScroll 4无法使用表单<select>元素iPhone Safari和Android浏览器

Actually, your issue is related to this question: 实际上,您的问题与此问题有关:

webkit-transform issue on safari using select elements 使用select元素在safari上进行webkit-transform问题

When an input gains focus in iOS Safari, it checks if the input is in view. 当输入在iOS Safari中获得焦点时,它会检查输入是否在视图中。 If it isn't, Safari forcibly scrolls the document, and the element(s) which contain the input, to make it visible. 如果不是,Safari会强制滚动文档以及包含输入的元素,以使其可见。

iScroll uses a CSS transform to move the scrollable area around, and it looks like Safari's behavior is broken for select s — it doesn't notice the transform, thinks that the select is out of view, and scrolls its container ( #scrollable ) to make it visible (again, not accounting for the transform), which puts it way out of view. iScroll使用CSS变换来移动可滚动区域,看起来Safari的行为因为select s而被破坏 - 它没有注意到变换,认为select不在视图中,并且将其容器( #scrollable )滚动到让它可见(再次,不考虑变换),这使它远离视野。

This is fundamentally an iOS bug, and should be reported to Apple by as many web developers as are affected by the issue! 这基本上是一个iOS错误,应该由受此问题影响的许多Web开发人员向Apple报告 A workaround can be implemented most effectively inside iScroll, so I encourage you to report the issue to its developers. 可以在iScroll内部最有效地实施解决方法,因此我建议您向其开发人员报告该问题。

That said, I have come up with a workaround, which you'll find at the bottom of this answer. 也就是说,我已经提出了一个解决方法,你可以在这个答案的底部找到。 You can use it by calling it, once, with your instance of iScroll: 您可以通过使用iScroll实例调用它一次来使用它:

workAroundiScrollSelectPositioning(myScroll);

A live demo is at your jsbin paste here . 现场演示为您jsbin贴在这里 It triggers when a select gains focus, and does three things: 它会在select获得焦点时触发,并执行以下三项操作:

  1. Remembers the scroll position, and tells iScroll to immediately scroll to the top left corner (removing any transform), and sets the top and left CSS properties of the scroll area to the current scroll position. 记住滚动位置,并告诉iScroll立即滚动到左上角(删除任何变换),并将滚动区域的topleft CSS属性设置为当前滚动位置。 Visually, everything looks the same, but the scroll area is now positioned in a way that Safari will see. 在视觉上,一切看起来都一样,但滚动区域现在以Safari将看到的方式定位。

  2. Block iScroll from seeing any touches (this is ugly, but it stops iScroll from applying a transform on the scroll area while we have it repositioned). 阻止iScroll看到任何触摸(这很难看,但它会阻止iScroll在滚动区域应用转换时重新定位)。

  3. When the select loses focus, put everything back to the way it was (restore the original position and transform and stop blocking iScroll). select失去焦点时,将所有内容恢复原样(恢复原始位置并转换并停止阻止iScroll)。

There are still cases where the element's position can get screwed up (eg when a textarea has focus but is only partially in view, and you type and cause Safari to try to bring the rest of it in view), but these are best fixed in 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);
}

you can use a custom table view on that place, suppose you want to show drop down list when user click on textfield. 您可以在该位置使用自定义表视图,假设您想在用户单击文本字段时显示下拉列表。 so when the user clcik on the textfield the delegate method get called TextFieldBeginEditing and inside that create a small table view . 所以当用户clcik在textfield上时,委托方法会调用TextFieldBeginEditing并在里面创建一个小表视图。 that look like a drop down list ... 看起来像一个下拉列表......

This is modified function workAroundiScrollSelectPositioning that worked for me. 这是修改过的函数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);}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM