3

The problem:

When the input is selected I want the screen to scroll so that the focused input is right at the top of the screen.

I want this to work on iOS and all other mobile devices.


This is what happens currently on iOS:

enter image description here


This is what I want to happen... Notice where the page scrolls to:

enter image description here


The code I'm currently trying out is:

$('#input').on('focus focusin', function(e) {
    e.preventDefault();
    $('html').animate({
        scrollTop: $('#anchor').offset().top
    }, 300);
})

This code works great on desktop, but as soon as I load the page up on my iPhone, it stops working completely and the default scroll behaviour takes over—as seen in the first gif.

Jarrod
  • 1,655
  • 2
  • 21
  • 35
  • Can you try with `body` instead of `html`? Like this `$('body').animate({...` – John R Dec 06 '17 at 08:38
  • @JohnR tried that, doesn't work at all when `body` is used instead of `html` – Jarrod Dec 06 '17 at 22:46
  • You may try this solution: https://stackoverflow.com/a/9298941/1736186 of course change 0 to `offset().top`. In the second answer I can see that `e.preventDefault()` doesn't work since IOS 8. Also there is one more hack that I have in mind but it's kind of ugly. Use `setTimeout()` with about 300ms(?) delay to check if `window.scrollTop()` is equal to what You want. Otherwise repeat scroll animation. And check this ONLY if this is touch device: https://stackoverflow.com/a/4819886/1736186 – instead Dec 07 '17 at 23:08
  • the problem is trying to change the default scroll behaviour – Walle Cyril Dec 09 '17 at 12:38
  • Can you try using position instead of offset? – tiborK Dec 11 '17 at 21:48

2 Answers2

4

So you just need it to scroll so the top of the input becomes the top of the screen?

I have added 2 pixels gap above the input so that you can see the border at the top of the input still.

$('#input').on('focus', function(e) {
    e.preventDefault();
    $('html, body').animate({
        scrollTop: $(this).offset().top-2;
    }, 1000);
})
Barkermn01
  • 6,781
  • 33
  • 83
2

Figured out the problem finally!

After hours and hours of mucking around, I figured out that the problem wasn't the code. The code shown in my question worked perfectly.

The problem happened to be my local testing environment (python manage.py runserver 0.0.0.0:8000 in command prompt).

I still haven't pinpointed the reason. I have however determined that I'm using Django 1.11.4 and jQuery 3.1.1 on both production and local testing environments. So why this problem would occur is beyond me.


My best guess is that there is some incompatibility between jQuery and Django's local testing server.

Jarrod
  • 1,655
  • 2
  • 21
  • 35