Demnogonis
Demnogonis

Reputation: 3222

jQuery Mobile page jumping to top when a collapsible is clicked

I have a jQuery Mobile page with a panel navigation. The last two elements are collapsibles with further menu items. Expanding or collapsing these causes the page to jump to the top and the user has to scroll down again to choose one of the revealed entries.

I tried to surpress this behaviour by executing .preventDefault() in the click event of the collapsible div, but the page still jumps to the top.

Does anyone know how to prevent this?

Thanks in advance.

My HTML:

<div data-role="panel" id="panel" data-position="left" data-theme="a" data-display="overlay" data-position-fixed="true" >
    <ul class="ui-listview" id="main_nav" data-role="listview" data-theme="a" >
        <!-- lots of other items -->  
        <li class="custom-li" data-icon="carat-r" >
            <div data-role="collapsible" data-iconpos="right" class="custom-collapsible" data-theme="a">
                <h2>Mein Account</h2>
                <ul class="ui-listview mainNav" data-role="listview" data-theme="a" >
                    <li id="nav_account" data-icon="carat-r">
                        <a href="#" onclick="return ajax_content('settings/account');" data-rel="close">Account Verwalten</a>
                    </li>
                    <li id="nav_profile_edit" data-icon="carat-r">
                        <a href="#" onclick="return ajax_content('settings/profile_edit');" data-rel="close">Profil bearbeiten</a>
                    </li>
                    <li id="nav_profile_interview" data-icon="carat-r">
                        <a href="#" onclick="return ajax_content('settings/profile_interview');" data-rel="close">Profil Interview bearbeiten</a>
                    </li>
                    <li id="nav_profile_pic" data-icon="carat-r">
                        <a href="#" onclick="return ajax_content('settings/profile_pic');" data-rel="close">Profilbild hochladen</a>
                    </li>
                </ul>
            </div>
        </li>
        <li class="custom-li" data-icon="carat-r" >
            <div data-role="collapsible" data-iconpos="right" class="custom-collapsible" data-theme="a">
                <h2>AGB / Impressum</h2>
                <ul class="ui-listview mainNav" data-role="listview" data-theme="a" >
                    <li id="nav_profile_edit" data-icon="carat-r">
                        <a href="#" onclick="ajax_content('impressum')" data-rel="close">Impressum</a>
                    </li>
                    <li id="nav_profile_intervview" data-icon="carat-r">
                        <a href="#" onclick="ajax_content('agb')" data-rel="close">AGB</a>
                    </li>
                    <li id="nav_profile_pic" data-icon="carat-r">
                        <a href="#" onclick="ajax_content('datenschutz')" data-rel="close">Datenschutz</a>
                    </li>
                </ul>
            </div>
        </li>
    </ul>
</div>

Custom CSS:

#main_nav .custom-li {
    padding: 0 !important;
    border-width:0 !important;
}

#main_nav .custom-bottom-li {
    border-top-width: 0 !important;  
}

#main_nav .custom-collapsible {
    margin-top:-7px;
    margin-bottom: -9px;
    border-bottom-right-radius: 0 !important;
    border-bottom-left-radius: 0 !important;
    border-top-right-radius: 0 !important;
    border-top-left-radius: 0 !important;
    border-width:0 !important;
}

#main_nav .ui-collapsible-content{
    margin-top: -7px !important;
    margin-bottom: 7px !important;
}

Upvotes: 4

Views: 4178

Answers (3)

matpop
matpop

Reputation: 2020

This appears to be an open bug:
https://github.com/jquery/jquery-mobile/issues/7055
https://github.com/jquery/jquery-mobile/issues/6688

As a raw fix for now, a script like this can be placed after the reference to jQuery Mobile source:

$(function() {
    $.mobile.panel.prototype._positionPanel = function() {
        var self = this,
            panelInnerHeight = self._panelInner.outerHeight(),
            expand = panelInnerHeight > $.mobile.getScreenHeight();

        if ( expand || !self.options.positionFixed ) {
            if ( expand ) {
                self._unfixPanel();
                $.mobile.resetActivePageHeight( panelInnerHeight );
            }
          //window.scrollTo( 0, $.mobile.defaultHomeScroll );
        } else {
            self._fixPanel();
        }
    };
});

This will override the widget internal method (note the commented line) without the need of changing jQuery Mobile source code directly (which is not possible when the framework is loaded from CDN).

Here's a live example.

Upvotes: 3

A Paul
A Paul

Reputation: 8271

One suggestion use "javascript:void(0);" instead of "#" in href. You can check it this works. If your onclick fail for some reason to return false like an error at run time. This will save you.

Upvotes: 2

franchez
franchez

Reputation: 567

Please add return false; as a final return in each onclick call.

For example:

onclick="ajax_content('impressum'); return false;"

And finally, instead of doing

return ajax_content('settings/profile_pic');

Just call ajax_content without return, add a return false after, and move your logic (what return is supposed to do) inside your ajax_content block.

Upvotes: 0

Related Questions