<选择>使用 iScroll4 脚本在 iPhone 浏览器中下拉焦点闪烁

发布于 2024-11-03 06:27:28 字数 366 浏览 1 评论 0原文

在 iPhone 中查看此演示页面 http://jsbin.com/unese4/8 底部页面有一个下拉菜单可以打开但无法正常工作。

这个问题与这个问题相关 iScroll 4 不适用于表单

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

甜味超标? 2024-11-10 06:27:28

事实上,你的问题与这个问题有关:

使用 select 元素的 safari 上的 webkit-transform 问题

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

iScroll 使用 CSS 转换来移动可滚动区域,并且 Safari 的行为似乎因 select 而被破坏 - 它没有注意到转换,认为 select在视图之外,并滚动其容器(#scrollable)以使其可见(同样,不考虑变换),这使其远离视图。

这从根本上来说是一个 iOS 错误,应该由尽可能多的受该漏洞影响的 Web 开发者向 Apple 报告问题!在 iScroll 中可以最有效地实施解决方法,因此我鼓励您向其开发人员报告该问题。

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

workAroundiScrollSelectPositioning(myScroll);

现场演示位于您的 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);
}

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);
}
苦妄 2024-11-10 06:27:28

您可以在该位置使用自定义表格视图,假设您想在用户单击文本字段时显示下拉列表。
因此,当用户在文本字段上单击时,委托方法将被调用 TextFieldBeginEditing 并在其中创建一个小表视图。看起来像一个下拉列表......

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

梦冥 2024-11-10 06:27:28

这是对我有用的修改后的函数 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);}

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);}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文