28

Hi is it possible to disable window scrolling without using overflow:hidden; when i'm hover an element?

i tryed :

$('.chat-content').on('mouseenter',function(){
    $(document).scroll(function(e){
        if(!$(e).hasClass('.chat-content'))
        e.stopPropagation();
        e.preventDefault();
    });
});

i mean, i want to leave visible the scrollbar but when i scroll out of the element i'm over with mouse the window doesn't scrolls, while the element i'm over can scroll

So disable scroll for body but not for element i'm over without using css

here is another try i did: http://jsfiddle.net/SHwGL/

itsme
  • 47,321
  • 93
  • 214
  • 341

8 Answers8

46

Try to handler 'mousewheel' event on all nodes except one

$('body').on({
    'mousewheel': function(e) {
        if (e.target.id == 'el') return;
        e.preventDefault();
        e.stopPropagation();
    }
})

Demo: http://jsfiddle.net/DHz77/1/

Ryan Wheale
  • 22,467
  • 7
  • 67
  • 87
Glen Swift
  • 11,879
  • 14
  • 45
  • 77
  • 2
    nope this blocks all elements scrolling, i wanna be able to scroll element i'm over – itsme Nov 06 '13 at 17:58
  • This block scrolling on the element with id elementid only. Proof: http://jsfiddle.net/DHz77/ – Glen Swift Nov 06 '13 at 18:05
  • It seems like I catch your question wrong for the first time. I've updated the answer. – Glen Swift Nov 06 '13 at 18:12
  • seems not working yet, check my question i updated my code ;) – itsme Nov 06 '13 at 19:37
  • Be careful: 'on({' You've lost the bracket :) – Glen Swift Nov 06 '13 at 21:56
  • uh? :D sorry but i can't this working yet :( i tryed your code too but i use hasClass() and it doesn't works as expected in your jsfiddle example :( – itsme Nov 07 '13 at 20:50
  • There is a working code in example as you can see in jsfiddle. Compare your code with mine carefully, and if everything right so you has a mistake in another part of programm – Glen Swift Nov 07 '13 at 23:59
  • i mean you block body scroll on element hover but didn't unblock on element mouseout, that is the step i'm missing, any clue pls? :) – itsme Nov 08 '13 at 08:27
  • 1
    This won't work in Firefox. For making it work in FF you should listen to 'DOMMouseScroll' event, – tomericco Mar 10 '14 at 17:35
  • 1
    @tomericco DOMMouseScroll event is deprecated. Maybe you're using old version of firefox? Reference: https://developer.mozilla.org/en-US/docs/DOM/DOM_event_reference/DOMMouseScroll – Glen Swift Mar 19 '14 at 16:57
  • this is the answer for google chrome. works well on chrome extension. – Teoman shipahi Jun 09 '14 at 18:03
  • How do you reenable the scroll? – rotaercz Dec 13 '14 at 23:24
  • @rotaercz add flag scrollDisabled and check it in condition too. Something like `if (e.target.id == 'el' && scrollDisabled) return;` – Glen Swift Dec 13 '14 at 23:26
  • Excelent answer, but you should be using `wheel` event instead for non-jquery implementations . It is standard among all recent and even older browsers (chrome 31+, IE 9+, FF 17+). – Vinícius Negrão May 18 '17 at 13:50
6

If you want to scroll the element you're over and prevent the window to scroll, here's a really useful function :

$('.Scrollable').on('DOMMouseScroll mousewheel', function(ev) {
    var $this = $(this),
        scrollTop = this.scrollTop,
        scrollHeight = this.scrollHeight,
        height = $this.height(),
        delta = (ev.type == 'DOMMouseScroll' ?
            ev.originalEvent.detail * -40 :
            ev.originalEvent.wheelDelta),
        up = delta > 0;

    var prevent = function() {
        ev.stopPropagation();
        ev.preventDefault();
        ev.returnValue = false;
        return false;
    }

    if (!up && -delta > scrollHeight - height - scrollTop) {
        // Scrolling down, but this will take us past the bottom.
        $this.scrollTop(scrollHeight);

        return prevent();
    } else if (up && delta > scrollTop) {
        // Scrolling up, but this will take us past the top.
        $this.scrollTop(0);
        return prevent();
    }
});

Apply the class "Scrollable" to your element and that's it!

pmrotule
  • 7,915
  • 3
  • 43
  • 54
  • 1
    @vsync - This code is not to disable the scroll, it's just to prevent the window to scroll when your mouse is over the specific element: when you reached the end of the scroll, it will start scrolling the window (that's what this code prevents). It won't happen if you scroll by dragging the scrollbar. – pmrotule Nov 09 '15 at 19:17
2

Following Glens idea, here it goes another possibility. It would allow you to scroll inside the div, but would prevent the body to scroll with it, when the div scroll ends. However, it seems to accumulate too many preventDefault if you scroll too much, and then it creates a lag if you want to scroll up. Does anybody have a suggestion to fix that?

    $(".scrollInsideThisDiv").bind("mouseover",function(){
       var bodyTop = document.body.scrollTop;
       $('body').on({
           'mousewheel': function(e) {
           if (document.body.scrollTop == bodyTop) return;
           e.preventDefault();
           e.stopPropagation();
           }
       });
    });
    $(".scrollInsideThisDiv").bind("mouseleave",function(){
          $('body').unbind("mousewheel");
    });
Fabio Nolasco
  • 6,450
  • 5
  • 34
  • 32
1

tfe answered this question in another post on StackOverflow: Answered

Another method would be to use:

$(document).bind("touchmove",function(event){
  event.preventDefault();
});

But it may prevent some of the jquery mobile functionality from working properly.

Community
  • 1
  • 1
shat
  • 212
  • 2
  • 5
  • 13
1

Without external variables:

       $('.element').bind('mousewheel', function(e, d) {
            if((this.scrollTop === (this.scrollHeight - this.offsetHeight) && d < 0)
                || (this.scrollTop === 0 && d > 0)) {
                e.preventDefault();
            }
        });
egor.xyz
  • 2,489
  • 1
  • 19
  • 17
0

CSS 'fixed' solution (like Facebook does):

body_temp = $("<div class='body_temp' />")
    .append($('body').contents())
    .css('position', 'fixed')
    .css('top', "-" + scrolltop + 'px')
    .width($(window).width())
    .appendTo('body');

to toggle to normal state:

var scrolltop = Math.abs($('.body_temp').position().top);
$('body').append($('.body_temp').contents()).scrollTop(scrolltop);
Jeaf Gilbert
  • 10,775
  • 17
  • 74
  • 100
0

Plenty of good ideas on this thread. I have a lot of popups in my page for handling user input. What I use, is a combination of disabling the mousewheel and hiding the scrollbar:

this.disableScrollFn= function(e) { 
    e.preventDefault(); e.stopPropagation() 
};
document.body.style.overflow = 'hidden';
$('body').on('mousewheel', this.disableScrollFn);

Advantage of this is we stop the user from scrolling in any possible way, and without having to change css position and top properties. I'm not concerened about touch events, since touch outside would close the popup.

To disable this, upon closing the popup I do the following.

document.body.style.overflow = 'auto';
$('body').off('mousewheel', this.disableScrollFn);

Note, I store a reference to my disableScrollFn on the existing object (in my case a PopupViewModel), for that gets triggered upon closing the popup to have access to disableScrollFn.

Shakus
  • 401
  • 5
  • 8
-1

You can use jquery-disablescroll to solve the problem:

  • Disable scrolling: $window.disablescroll();
  • Enable scrolling again: $window.disablescroll("undo");

Supports handleWheel, handleScrollbar, handleKeys and scrollEventKeys.

Martin Tournoij
  • 24,971
  • 24
  • 101
  • 136
Thomas
  • 29
  • 6
  • 1
    A link to a potential solution is always welcome, but please [add context around the link](http://meta.stackoverflow.com/a/8259) so your fellow users will have some idea what it is and why it’s there. Always quote the most relevant part of an important link, in case the target site is unreachable or goes permanently offline. Take into account that being _barely more than a link to an external site_ is a possible reason as to [Why and how are some answers deleted?](http://stackoverflow.com/help/deleted-answers). – Tunaki Nov 26 '16 at 23:25