8

I have already found the solution in the accepted answer here:

How to prevent page scrolling when scrolling a DIV element?

But want also to disable scrolling the main page on keys (when div content can't be scrollable anymore).

I'm trying to make something like this but it's not working:

$( '.div-scroll' ).bind( 'keydown mousewheel DOMMouseScroll', function ( e ) {
                var e0 = e.originalEvent,
                delta = e0.wheelDelta || -e0.detail;

                this.scrollTop += ( delta < 0 ? 1 : -1 ) * 30;

                if([32, 37, 38, 39, 40].indexOf(e.keyCode) > -1) {
                    e.preventDefault();
                }
                e.preventDefault();
            });

Any ideas why?

Community
  • 1
  • 1
FreakSoft
  • 363
  • 2
  • 3
  • 12

3 Answers3

12

You can stop the scrolling of the whole page by doing:

Method 1

<div  onmouseover="document.body.style.overflow='hidden';"  onmouseout="document.body.style.overflow='auto';"></div>

but it makes the browser's scrollbar disappear whenever you hover over the div.

Method 2

Else you can look at jquery-mousewheel.

var toolbox = $('#toolbox'),
    height = toolbox.height(),
    scrollHeight = toolbox.get(0).scrollHeight;

toolbox.off("mousewheel").on("mousewheel", function (event) {
  var blockScrolling = this.scrollTop === scrollHeight - height && event.deltaY < 0 || this.scrollTop === 0 && event.deltaY > 0;
  return !blockScrolling;
});

DEMO

Method 3

To stop the propagation with no plugins.

HTML

<div class="Scrollable">
  <!-- A bunch of HTML here which will create scrolling -->
</div>

JS

$('.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();
    }
});

Method 4

you can do it by canceling these interaction events:

Mouse & Touch scroll and Buttons associated with scrolling.

// left: 37, up: 38, right: 39, down: 40,
// spacebar: 32, pageup: 33, pagedown: 34, end: 35, home: 36
var keys = {37: 1, 38: 1, 39: 1, 40: 1};

function preventDefault(e) {
  e = e || window.event;
  if (e.preventDefault)
      e.preventDefault();
  e.returnValue = false;  
}

function preventDefaultForScrollKeys(e) {
    if (keys[e.keyCode]) {
        preventDefault(e);
        return false;
    }
}

function disableScroll() {
  if (window.addEventListener) // older FF
      window.addEventListener('DOMMouseScroll', preventDefault, false);
  window.onwheel = preventDefault; // modern standard
  window.onmousewheel = document.onmousewheel = preventDefault; // older browsers, IE
  window.ontouchmove  = preventDefault; // mobile
  document.onkeydown  = preventDefaultForScrollKeys;
}

function enableScroll() {
    if (window.removeEventListener)
        window.removeEventListener('DOMMouseScroll', preventDefault, false);
    window.onmousewheel = document.onmousewheel = null; 
    window.onwheel = null; 
    window.ontouchmove = null;  
    document.onkeydown = null;  
}
Darren Willows
  • 2,053
  • 14
  • 21
  • Yeah, I know how to prevent keys scrolling but don't know how to incorporate this into the code I provided that only the .div-scroll element can use arrows to scroll and not the whole page where I'm in the bottom/top of the .div-scroll element and hit up/down arrow. – FreakSoft Nov 12 '15 at 14:24
  • When the above method 4 is used, when the scrollable list reaches the bottom, the main / container div starts scrolling again, which seems like an odd thing, considering that no mouseout should've been triggered yet. – Neil S3ntence Jun 11 '16 at 16:04
4

You need to bind document to 'keydown' event like this:

$( document ).bind( 'keydown', function (e) { ... e.preventDefault(); }
Vnuuk
  • 6,177
  • 12
  • 40
  • 53
  • Yeah, I know how to prevent keys scrolling but don't know how to incorporate this into the code I provided that only the .div-scroll element can use arrows to scroll and not the whole page where I'm in the bottom/top of the .div-scroll element and hit up/down arrow. – FreakSoft Nov 12 '15 at 14:24
3

This code block the scrolling by using keys:

$(document).keydown(function(e) {
        if (e.keyCode === 32 || e.keyCode === 37 || e.keyCode === 38 || e.keyCode === 39 || e.keyCode === 40) {
            return false;
        }
});
Nvan
  • 1,126
  • 16
  • 23
  • Yeah, I know how to prevent keys scrolling but don't know how to incorporate this into the code I provided that only the .div-scroll element can use arrows to scroll and not the whole page where I'm in the bottom/top of the .div-scroll element and hit up/down arrow. – FreakSoft Nov 12 '15 at 14:24