So I\'m developing a jQuery mobile phonegap app and I noticed that every time I open the panel the main page scrolls to the top automatically. I want the page to remain at t
Have you tried putting an event handler in the function and using e.preventDefault();
function (e) {e.preventDefault}
Its just the way JQM works at the moment till probably Version 2 until scroll physics are in place.
There are some ways around it for now. If you have a lot of items on the panel then i recommend using Iscroll 5 http://cubiq.org/iscroll-5 or if you are using Iscroll plugging already then create a scroller for the panel.
However if the items are not that many and you are not using the Iscroll plugging the methods below work well.
Method A. Using CSS to make the inner part of the panel contents scroll independent from the main content page and avoid dual scrolling.
CSS fix JQM 1.3, 1.4+
.ui-panel.ui-panel-open {
position:fixed;
}
.ui-panel-inner {
position: absolute;
top: 1px;
left: 0;
right: 0;
bottom: 0px;
overflow: scroll;
-webkit-overflow-scrolling: touch;
}
i have this in my panel
data-position-fixed="true"
For 1.3 only, This is a small hack to stop the main page scrolling when the panel is scrolled right to the top or right to the bottom and the user keeps scrolling.
.ui-page-active.ui-page-panel {
height: 70%;
}
Demo
http://jsfiddle.net/qsXzD/5/
Method B. Because the listview scrolls on top when the panel opens this method remembers the last scroll position on the main listview and animates to it upon Panel Close.
CSS
::-webkit-scrollbar { width: 0px; }
.ui-panel.ui-panel-open {
position:fixed;
}
.ui-panel-inner {
position: absolute;
width:100%;
top: 0px;
bottom: -17px;
overflow: scroll;
-webkit-overflow-scrolling: touch;
}
J-query. store the Position of the (List-view as we scroll).
Just to note the storePosition.topCoordinate !== 0 condition is there so we can avoid animating if we are right to the top of the list-view to save some CPU cycles.
var storePosition = {
topCoordinate : null
}
$(document).ready(function(){
$( "#mypanel" ).panel({
beforeopen: function( event, ui ) {
storePosition.topCoordinate = $(this).offset().top;
$( ".ui-mobile [data-role=page], .ui-mobile [data-role=dialog], .ui-page" ).css("position","fixed");
}
});
$( "#mypanel" ).panel({
close: function( event, ui ) {
$( ".ui-mobile [data-role=page], .ui-mobile [data-role=dialog], .ui-page" ).css("position","");
if($.mobile.activePage.attr("id") == "index" && storePosition.topCoordinate !== 0){
$('html, body').animate({
scrollTop: $("#mainlist").position().top += storePosition.topCoordinate - 60
}, 1000);
}
}
});
});
DEMO 1 with one second animation scrolling after panel-close. Scroll down anywhere, open the panel and then close the Panel.
http://jsfiddle.net/srym7v4m/
DEMO 2 instant animation scrolling before panel-close. Scroll down anywhere, open the panel and then close the Panel.
http://jsfiddle.net/3yyjkkya/
Changes
$( "#mypanel" ).panel({
beforeclose: function( event, ui ) {
$( ".ui-mobile [data-role=page], .ui-mobile [data-role=dialog], .ui-page" ).css("position","");
if($.mobile.activePage.attr("id") == "index" && storePosition.topCoordinate !== 0){
$('html, body').animate({
scrollTop: $("#mainlist").position().top += storePosition.topCoordinate - 60
}, 10);
}
}
});
})
Update 16 November 2014.
there is a nice guide here on how you can achieve Native Scrolling, which keeps scrolling positions even when you navigate from one page to the next
http://outof.me/native-scrolling-in-jquery-mobilephonegap-applications/
the demo is for an older version of JQM but works fine with the latest 1.4.5
for the panels to work independently you need to add the following css
.ui-panel-inner {
position: absolute;
width: 240px;
max-width: 240px;
top: 0px;
bottom: 0px;
overflow: scroll;
-webkit-overflow-scrolling: touch;
}
if you intent to have the Panels larger than the default width: 17em;
then adjust the width and max width in .ui-panel-inner
Demo
http://jsfiddle.net/6zhdnen0/
I've recently encountered this and come up with the following solution.
1.- When user clicks Menu link, run a function called menuOpen
function menuOpen(){
var scrollTop = window.document.body.scrollTop;
//You can replace this with a regular menu open. I use some code that places the same menu panel on every page so that I only have to write it once, but it causes a duplicate ID of "menupanel"- hence the code that will only open #menupanel on the current active page
$.mobile.activePage.find('#menupanel').panel("open");
window.document.body.scrollTop = scrollTop;
}
Here is an option I wrote. It takes the approach of storing the scroll position of the page before a panel opens and restoring it when the panels closes. I have some really long panels and this worked for me. This has been written generically so it wires up to all panels. You can change the selectors to wire up against just certain panels.
/*******************************************************************************
* When a panel opens, it makes you lose your place whithin the main page.
* These functions fix that by tracking where you are in the page before the
* panels opens and restoring that position when the panel closes
******************************************************************************/
$(document).on("panelbeforeopen", "[data-role=page]", function(e) {
/* if page we're leaving is a regular page, store the scroll position */
if ($.mobile.activePage.attr("data-role")=="page" && $("body").scrollTop()!=0)
{
window._scrollTop = $("body").scrollTop();
}
});
$(document).on("panelopen", "[data-role=panel]", function(e) {
/* when the panel finishes opening scroll to the top
$.mobile.silentScroll(0);
});
$(document).on("panelclose", "[data-role=panel]", function(e) {
/* when the panel closes, restore the last stored scroll position */
$.mobile.silentScroll(window._scrollTop);
});