user1630809
user1630809

Reputation: 532

jquery mobile 1.4.2 scroll to div after pageContainer change

after not finding a way to use anchor position after pageContainer change event in a multipage ajax enabled mobile application, I have tried to investigate if it is possible to silent scroll to a specific div element after that event, but without success.

Code is:

$("#myPage").html('<div id="mydiv">Hello</div>');
$.mobile.pageContainer.pagecontainer("change", "#myPage");
$('html,body').animate({
            scrollTop: $('#mydiv').offset().top}, 'slow');

$('#mydiv').offset().top is always 0!

Even if I define this event:

$(document).on('pagecontainershow', function(e, ui) {
    var pageId = $('body').pagecontainer('getActivePage').prop('id');

    if (pageId == 'myPage')
    {
       $('html,body').animate({
                scrollTop: $('#mydiv').offset().top}, 'slow');
    }
});

scroll is not triggered.

Basically my need is to change html of a page, change page to this one and scroll to a specific div which is dynamically created.

Thanks for your suggestion

Upvotes: 2

Views: 2153

Answers (1)

0not
0not

Reputation: 190

I just ran into this same problem. I cannot believe how complicated it is to do this. The problem is that in the context you call animate() your div #mydiv is not displayed and therefore has an offset() of 0. This should be fixed by your on(), but you have to make sure to declare it before you change the page. I believe that (as of jQM 1.4) only body can be the .selector mentioned in the documentation.

The following works for me:

$("body").on("pagecontainershow", function(event, ui) {
    if($.mobile.activePage.attr('id') == "myNewPage" && ui.prevPage[0].id == "myOldPage")
        $("html,body").animate({scrollTop: $("#mydiv").offset().top}, 0);
});
$("body").pagecontainer("change", "#myNewPage");

You might look into one() if the show event should only be handled once.

EDIT: Made plunker based on above code.

<link rel="stylesheet" href="http://code.jquery.com/mobile/1.4.2/jquery.mobile-1.4.2.min.css" />
<script src="http://code.jquery.com/jquery-1.11.1.min.js"></script>
<script src="http://code.jquery.com/mobile/1.4.2/jquery.mobile-1.4.2.min.js"></script>
<script>
  $(document).on("pagebeforeshow", function(){
    $("#click_me").click(function (e) {
      $("body").on("pagecontainershow", function(event, ui) {
        if($.mobile.activePage.attr('id') == "two" && ui.prevPage[0].id == "one")
          $("html,body").animate({scrollTop: $("#after_hello").offset().top}, 500);
      });
      $('body').pagecontainer('change', '#two');
    });
  });
</script>

And the summarized HTML:

<div id="one" data-role="page">
  <div data-role="main">
    <button id="click_me">Click to change and scroll</button>
  </div>
</div>
<div id="two" data-role="page">
  <div data-role="main">
    <div>...</div>
    <h1>Hello!</h1>
    <div id="after_hello">...</div>
  </div>
</div>

EDIT 2: OP provided a plunker that needed just one change to work. Here is the modified version. I changed the animate selector from $("html,body") to $("#maintesto"). This is probably needed due to the fixed header. I also added more "lorem ipsum" content to see the effect on my larger screen.

Upvotes: 1

Related Questions