7

We use jQuery mobile for m.swisswebcams.ch. When I scroll down while the page is still loading, it seems to always jump up again on page load (i.e. window.onload).

How can this be fixed?


Steps to reproduce this issue:

  1. Open m.swisswebcams.ch in your mobile browser
  2. Scroll down immediately while the page is still loading
  3. Wait until the page jumps to top by itself
  4. (It does not always happen. So you might need to try again sometimes.)

Result

Opening website:

enter image description here

Scrolling down:

enter image description here

Automatically jumps to top (unwanted):

enter image description here

Simon Ferndriger
  • 4,455
  • 6
  • 28
  • 53
  • What happens if you comment this out: `data.deferred.resolve( data.absUrl, data.options, page );` – mplungjan Jan 25 '17 at 12:54
  • I think this is a known issue with jquery mobile, view this [link](http://stackoverflow.com/questions/31474402/after-jquery-mobile-pageshow-silentscroll-page-jumps-to-top) – Aminur Rashid Jan 25 '17 at 13:30
  • @mplungjan You are right, yelling does not help to solve, but to feel better since this bug seems to be there for a long time and nobody at jQuery seems to care about it. So anyway, thank you for your help. But where do you see "data.deferred.resolve", I looked for it in http://ajax.googleapis.com/ajax/libs/jquerymobile/1.4.5/jquery.mobile.min.js and didn't find it. – Simon Ferndriger Jan 27 '17 at 10:42
  • I saw it on your site. – mplungjan Jan 27 '17 at 10:44
  • @AminurRashid It may be related, but it is not the same, since I don't do any silenscrolling myself like in the example you mentioned. Please rate this question up, because this bug is really annoying and somehow nobody cares about it. – Simon Ferndriger Jan 27 '17 at 10:44
  • @mplungjan Thanks, I commented it out on our dev page (replace "m." width "dev-m."), but it didn't change anything – Simon Ferndriger Jan 27 '17 at 10:49
  • IMHO: when you fire an URL / a request it is normal browser behaviour to jump at the top of a page, also when your fire an url via javascript, for example with document.location = ... - Only ajax requests or browser functionalities like "F5 refresh" keep the document scroll position. – Gunnar Jan 27 '17 at 13:07
  • @Gunnar What do you mean by "fire an URL"? I don't fire anything, I just load the page. – Simon Ferndriger Jan 30 '17 at 13:25
  • @mplungjan Didn't change anything (at least on the iPhone). Any other ideas? Can you please vote this question up? – Simon Ferndriger Jan 30 '17 at 13:26
  • Why would I vote this up? it does not make it more visible and the question is very poor. I have not voted it down but it is not adhering to the [mcve] – mplungjan Jan 30 '17 at 13:28
  • I cannot reproduce the issue on my iPhone on Chrome but on Safari it jumps after the advert loaded. What happens if you drop the advert? – mplungjan Jan 30 '17 at 13:30
  • Simon, I'm just talking about the two ways of requesting an URL: one way is a "full" or "normal" or "non-javascript" request like entering an URL, clicking a link or submitting a form, the other way is the background ajax request where javascript fills the response in html containers. The first way **always** jumps to the top of the page when it's loaded (in all browsers IMHO, except when you refresh an already loaded page by F5 for example). Short and simple: "This behaviour is by design". – Gunnar Jan 31 '17 at 10:46

2 Answers2

3

Well, this behavior is by default in jQuery Mobile (actual v. 1.4.5). From jQuery Mobile source code:

    // hide iOS browser chrome on load if hideUrlBar is true this is to try and do it as soon as possible
    if ( $.mobile.hideUrlBar ) {
        window.scrollTo( 0, 1 );
    }

and this is the silentScroll function referenced in the previous comments:

....
    // Scroll page vertically: scroll to 0 to hide iOS address bar, or pass a Y value
    silentScroll: function( ypos ) {
        if ( $.type( ypos ) !== "number" ) {
            ypos = $.mobile.defaultHomeScroll;
        }

        // prevent scrollstart and scrollstop events
        $.event.special.scrollstart.enabled = false;

        setTimeout(function() {
            window.scrollTo( 0, ypos );
            $.mobile.document.trigger( "silentscroll", { x: 0, y: ypos });
        }, 20 );

        setTimeout(function() {
            $.event.special.scrollstart.enabled = true;
        }, 150 );
    },
...

This workaround is no longer valid since iOS 7, but was one of the most requested features to get in "full-screen mode" (see a lot of questions about that on SO).

This is actually the reference: iOS 8 removed "minimal-ui" viewport property, are there other "soft fullscreen" solutions? with a detailed explanation also for more recent versions of iOS.

Just guessing, maybe you didn't noticed this behavior because you have newer iOS versions, or you don't need to get fullscreen, as you are already doing a scroll by hand.

You can prevent the initial scroll top by overriding the JQM settings:

<script type="text/javascript">
    $(document).bind("mobileinit", function() {
        $.mobile.ajaxEnabled = false;
        $.mobile.hideUrlBar = false; // <---- add this line
    });


    var GLOBAL = {
        language : 'de'
    };
</script>

Try it out and let me know if this solves your issue. In my tests, it worked.

EDIT: This annoying behavior has been fixed in the upcoming 1.5 version of JQM:

Reference: jQuery Mobile 1.5.0-alpha1 Changelog

Fixed page load to Prevent silentScroll if user has already scrolled (#3958, 0996492)

Community
  • 1
  • 1
deblocker
  • 7,629
  • 2
  • 24
  • 59
-1

Like stated in the comment: This behaviour ist by design. There are two ways of requesting an URL: one way is a "full" or "normal" or "non-javascript" request like entering an URL, clicking a link or submitting a form, the other way is the background ajax request where javascript fills the response in html containers. The first way always jumps to the top of the page when it's loaded (in all browsers IMHO, except when you refresh an already loaded page by F5 for example).

Update

It's up to you as a website programmer to work around this browser behaviour. Just use the jQuery loader or jQuery Mobile events to show some status bar or spinning circle WHILE the page loads.

Gunnar
  • 383
  • 4
  • 18
  • Ah, OK, but why is this? It would make more sense if the page jumps to top right at the beginning of page loading/rendering/requesting and not at the end. Is it possible to change this trigger timing for the jump-to-top? – Simon Ferndriger Feb 01 '17 at 10:07
  • It is clearly not a user-friendly behaviour like this – Simon Ferndriger Feb 01 '17 at 10:08
  • This would be a browser programming request per browser, it's just "normal" behaviour. First you fill the cup, then you drink the coffee :-) With jquery mobile events you can 1.) show some indicator while the page loads and 2.) render the completely loaded page in the browser, see https://api.jquerymobile.com/category/events/ – Gunnar Feb 02 '17 at 11:07
  • 1
    OK, the coffee example makes sense :) And I understand this behaviour makes sense for (2), because the browser needs the website *first* before he can jump anywhere, but regarding (1) the website already starts showing while loading, so the browser should be able to jump to top - or to compare it with a normal website (non-jquery), it also shows parts of it while loading, but does not jump to top when the website loaded completely - or did I miss your point completely? – Simon Ferndriger Feb 03 '17 at 11:56