Disable scrolling when changing focus form elements ipad web app

To prevent the browser from scrolling to the element you move focus to I use jQuerys one event listener. Right before I move the focus to the element we add the listener to the scroll event and counter scroll. The event listener is than removed by jQuery.

var oldScroll = $(window).scrollTop();

$( window ).one('scroll', function() {
    $(window).scrollTop( oldScroll ); //disable scroll just once
});

$('.js-your-element').focus();

This way seems simple, effective to me and works great in all tests I have done.

Hope it helps someone.


I've found that in UIWebView, document.body is also sometimes moved. So I use:

    input.onfocus = function () {
        window.scrollTo(0, 0);
        document.body.scrollTop = 0;
    }

If you do not want the input to be editable the answer from kpozin works fine. But as soon as you remove the readonly attribute onfocus or onclick the input field scrolls in focus again.

What really helps and does not impact focus or ability to enter text is adding onFocus="window.scrollTo(0, 0);" to the input elements.

Of course you have to guarantee that the relevant input is not covered by the onscreen keyboard!

See also this post: Preventing an <input> element from scrolling the screen on iPhone?


Ooops, the window.scrollTo suggested is kinda lousy and make things unpredictable.

Try this better solution:

jQuery('body').bind('focusin focus', function(e){
  e.preventDefault();
})

Or, just hook your input:

jQuery('input.your-input-class').bind('focusin focus', function(e){
  e.preventDefault();
})

Why? Browsers may scroll the focused form element into view by default on 'focusin' event fired (Firefox has a bug, so hook on focus instead). So, just tell them don't do that explicitly.

BTW, if the focus event is triggered by element.focus() in your code, then even the upon solution would not be functional.

So, a solution to that would be replace you focus trigger to select, i.e.

element.select()

other than element.focus()

If you don't like the element.select() approach since it will select the text inside the input element, then try to create a Range object of the input element text and collapse it if you will, sorry for no time to try that at this moment.