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.
This question is related to this question iScroll 4 not working with form <select> element iPhone Safari and Android browser
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 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.
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:
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.
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).
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);}