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

馋奶兔 提交于 2019-12-03 17:27:46
s4y

Actually, your issue is related to this question:

webkit-transform issue on safari using select elements

When an input gains focus in iOS Safari, it checks if the input is in view. If it isn’t, Safari forcibly scrolls the document, and the element(s) which contain the input, to make it visible.

iScroll uses a CSS transform to move the scrollable area around, and it looks like Safari’s behavior is broken for selects — 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.

This is fundamentally an iOS bug, and should be reported to Apple by as many web developers as are affected by the issue! A workaround can be implemented most effectively inside iScroll, so I encourage you to report the issue to its developers.

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:

workAroundiScrollSelectPositioning(myScroll);

A live demo is at your jsbin paste here. It triggers when a select gains focus, and does three things:

  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. Visually, everything looks the same, but the scroll area is now positioned in a way that Safari will see.

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

  3. When the select loses focus, put everything back to the way it was (restore the original position and transform and stop blocking iScroll).

There are still cases where the element's position can get screwed up (e.g. 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.


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 . that look like a drop down list ...

This is modified function workAroundiScrollSelectPositioning that worked for me.

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);}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!