When viewed on a small screen, my website transforms its menu into a hamburger button. Clicking the button toggles a sidebar displaying a stacked version of the menu on top of the normal website (position: fixed; z-index: 5;
). This sidebar also triggers a body-overlay to prevent clicking on any links within the main site.
I am attempting to disable scrolling on the website's body while still allowing scrolling within the menu-sidebar, especially on devices like an iPhone 4 where the menu may extend beyond the screen size.
My initial solution involved setting overflow-y: hidden;
on the body when the sidebar is active and applying overflow-y: scroll;
to the sidebar itself. While this worked on a computer resized to mobile width, it had no effect on my iPhone – I found myself accidentally scrolling the body instead of the sidebar.
How can I effectively disable scrolling functionality on a mobile device?
I understand this could be achieved using JavaScript, but that would likely restrict scrolling within the menu-sidebar...
document.ontouchstart = function(e){
e.preventDefault();
}
https://i.sstatic.net/Q8eFs.png
Solved
HTML Structure
<body>
<div class="mobile-nav closed">
<!-- Menu -->
</div>
<div class="body-overlay"></div>
<!-- Page Content -->
</body>
jQuery Code
$( '.hamburger' ).on( 'click', function( e ) {
$( this ).toggleClass( 'is-active' );
$( '.mobile-nav' ).toggleClass( 'closed' );
$( '.body-overlay' ).fadeToggle( 300 );
$( 'body' ).toggleClass( 'no-scroll' ).promise().done( function(){
var touchScroll = function( event ) {
event.preventDefault();
};
if ( $(this).hasClass( 'no-scroll' ) ) {
$( '.body-overlay' ).bind( 'touchmove', touchScroll );
$( '.mobile-nav' ).unbind( 'touchmove', touchScroll );
}
else {
$( '.body-overlay' ).unbind( 'touchmove', touchScroll );
}
} );
e.preventDefault();
} );
This code functions well. The $('.hamburger')
represents the hamburger menu button, changing its class to .is-active
upon click. The second and third statements are self-explanatory. The fourth statement is crucial. By toggling the .no-scroll
class on the body, I enforce overflow-y: hidden
for the body and overflow-y: scroll
for the menu. Although mobile devices did not respond to this initially, a callback function addresses this issue. The function checks for the presence of the .no-scroll
class on the body (menu open) or absence (menu closed), enabling/disabling scrolling accordingly.
I hope this explanation helps! :)