最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - iOS Safari: Prevent (or Control) Scroll on Input Focus - Stack Overflow

programmeradmin0浏览0评论

There are a lot of old questions sort of (but not quite) about this, but as I couldn't find anything modern, I thought I'd ask again with the hope of receiving a modern answer.

I am working on a hobbyist responsive web app, but I'm having trouble with input focus on iOS. I would like the input to scroll to just above the iOS keyboard on focus (or not scroll), but iOS wants to center that control no matter what.

In the attached GIF, you can see the behavior I'm seeing, and then I scroll at the end to indicate what I'd like to happen as soon as the focus event is triggered.

One thing I found that sort of works, but I'd like something better: the following code works, but has a noticeable delay between the scroll you see in the GIF and the window returning to the position I'd like it. Also, if I adjust the setTimeout() timing below ~400, it doesn't work. Does iOS have some block during its focus scroll bump?

element.addEventListener('focus', (e) => { setTimeout(() => { window.scroll(0,0) }, 500) });

 

Update #1

So far, the only solution I've tried that's worked is the following, which feels pretty janky (where scrollLock is defined elsewhere in focus and blur listeners):

document.addEventListener('scroll', (e) => {
    if (scrollLock && document.documentElement.scrollTop > 100) {
        document.documentElement.scrollTop = 100;
    }
});

All the solutions involving preventDefault() or window.scroll calls have not prevented the scroll pictured above, but actively monitoring the scroll and forcing it back to where I want it does work. Would love for this not to be the answer, however!

There are a lot of old questions sort of (but not quite) about this, but as I couldn't find anything modern, I thought I'd ask again with the hope of receiving a modern answer.

I am working on a hobbyist responsive web app, but I'm having trouble with input focus on iOS. I would like the input to scroll to just above the iOS keyboard on focus (or not scroll), but iOS wants to center that control no matter what.

In the attached GIF, you can see the behavior I'm seeing, and then I scroll at the end to indicate what I'd like to happen as soon as the focus event is triggered.

One thing I found that sort of works, but I'd like something better: the following code works, but has a noticeable delay between the scroll you see in the GIF and the window returning to the position I'd like it. Also, if I adjust the setTimeout() timing below ~400, it doesn't work. Does iOS have some block during its focus scroll bump?

element.addEventListener('focus', (e) => { setTimeout(() => { window.scroll(0,0) }, 500) });

 

Update #1

So far, the only solution I've tried that's worked is the following, which feels pretty janky (where scrollLock is defined elsewhere in focus and blur listeners):

document.addEventListener('scroll', (e) => {
    if (scrollLock && document.documentElement.scrollTop > 100) {
        document.documentElement.scrollTop = 100;
    }
});

All the solutions involving preventDefault() or window.scroll calls have not prevented the scroll pictured above, but actively monitoring the scroll and forcing it back to where I want it does work. Would love for this not to be the answer, however!

Share Improve this question edited Mar 23, 2020 at 17:01 Josh Hattersley asked Mar 22, 2020 at 8:37 Josh HattersleyJosh Hattersley 3411 gold badge2 silver badges7 bronze badges 6
  • Do you have that much height to the container? Could you make window.scroll(0,0) work on click of a button or something rather than focus? – Rayon Commented Mar 22, 2020 at 8:45
  • The container height doesn't seem to matter to mobile Safari (and it's a flex container, but it shouldn't take more than available view height). And I could trigger on other than focus, but that won't solve that initial scroll iOS does. – Josh Hattersley Commented Mar 22, 2020 at 8:50
  • How about trying this solution? stackoverflow.com/a/38621037/1746830 Let me know how it goes. – Rayon Commented Mar 22, 2020 at 9:25
  • One of the solutions I came across is - Keep a hidden element somewhere around footer. Watch for focus event on input and make that hidden element visible. Maybe this would do the trick. – Rayon Commented Mar 22, 2020 at 10:08
  • Thanks for the research @Rayon! Unfortunately those solutions didn't work, but I did find one possibility that I've added as an update to the OP. – Josh Hattersley Commented Mar 23, 2020 at 17:01
 |  Show 1 more comment

3 Answers 3

Reset to default 3

One thing that worked for us is to call a scroll event 50ms after getting focus. So if you click into the text field a focus event is triggered. In that event we trigger a setTimeout(() => window.scrollTo(0,100), 50).

Similar issue with iOS 15, in my specific case the body was scrolling horizontally when an input element towards the right side of the page became focused. Adding position: fixed to the body and html elements fixed this for me, but I don't have any scrolling (Single Page App) so this may cause more problems for others.

I had a similar issue and came across this post while googling (for hours). I came back to post what worked for me in case it helps others.

Specifically I was using a bootstrap-vue modal with a text input and on focus/tap of the input field Android chrome would scroll to the bottom of the modal (looks similar to your video), if i scrolled back up and typed it stayed in focus but tapping again it would scroll again back to same spot.

Here's what worked:

html,body{
    -webkit-overflow-scrolling : touch !important;
    overflow: auto !important;
}

Original Credit to: https://stackoverflow.com/a/35675094/1625130

发布评论

评论列表(0)

  1. 暂无评论