Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Disable outer content's scrolling on touch based devices (Twitter bootstrap navbar)

I use twitter bootstrap 3. I added fixed top navbar. I have dropdown buttons on navbar. When user clicks on button, a dropdown menu opens. For desktop users it is ok. But for mobile users, when user scrolls down dropdown links, the page in the back also scrolls.

Is it possible to disable background page scroll when user scrolls dropdown links ?

Fiddle: http://jsfiddle.net/mavent/2g5Uc/1/

When user touches dropdown part and touches like the green arrow, background page scrolls like red arrow in this screenshot: enter image description here

<nav class="navbar navbar-inverse navbar-fixed-top visible-xs" role="navigation">
    <div class="navbar-header" style="text-align:center;">
     .......
    </div>

Edit: I checked that, that and that.

Edit: This doesn't work. This stops all page scrolling.

$('#my_navbar_div').bind('touchmove', function(event)
{
    event.preventDefault();
});

This doesn't work. Doesn't changed anything in behaviour:

$('#my_navbar_div').hover(function() {
    $(document).bind('touchstart touchmove',function(){
        $("body").css("overflow","hidden");
    });
}, function() {
    $(document).unbind('touchstart touchmove');
});
like image 983
trante Avatar asked Nov 15 '13 21:11

trante


2 Answers

To have more control of the scrolling abilities, you can try the following.

Disable all scrolling:

//create the exception variable.
var Scrollable = '.scrollable';

    //prevent all scrolling.
    $(document).on('touchmove', function(e) {
        e.preventDefault();
    });

    $('body').on('touchstart', Scrollable, function(e) {
        if (e.currentTarget.scrollTop === 0) {
            e.currentTarget.scrollTop = 1;
        } else if (e.currentTarget.scrollHeight === e.currentTarget.scrollTop + e.currentTarget.offsetHeight) {
            e.currentTarget.scrollTop -= 1;
        }
    });

The following is to allow scrolling on the exception:

    // Stops preventDefault from being called on document if it sees a scrollable div
    $('body').on('touchmove', Scrollable, function(e) {
        e.stopPropagation();
    });

What you want to do, is set a class called scrollable on every element that you want to be scrollable. You can of course always call the stopPropagation() when you want.

This way you can easily decide if you want something to be scrollable or not, overflow is not always working as you think it would.

I hope this helps.

Edit: You should also try to set the z-index of your #nav higher then the z-index of your body/content container.

like image 164
Billy Avatar answered Nov 12 '22 23:11

Billy


I had the same problem and I solved using Billy's answer as well as adding a class to the body when the menu is clicked.

In your CSS:

    .no-scroll{
         overflow: hidden;
         position: fixed;
         width: 100%;
    }

In your JavaScript do something like:

    $(".navbar-toggle").click(function() {
         if ($("#mobile-toggle-menu").hasClass("in")) {
             return $("body").removeClass("no-scroll");
         } else {
             return $("body").addClass("no-scroll");
         }
    });

I use CoffeeScript so I'm not 100% sure the JavaScript syntax is correct but this did the job for me and it works both on Android and iPhone.

like image 34
Stefania F. Cardenas Avatar answered Nov 12 '22 23:11

Stefania F. Cardenas