Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to disable scrolling in outer elements?

I have a vertically-scrolling div within a page that also scrolls vertically.

When the child div is scrolled with the mouse wheel and reaches the top or bottom of the scroll bar, the page (body) begins to scroll. While the mouse is over the child div, I'd like the page (body) scroll to be locked.

This SO post (scroll down to the selected answer) demonstrates the problem well.

This SO question is essentially the same as mine, but the selected answer causes my page contents to noticeably shift horizontally as the scrollbar disappears and reappears.

I thought there might be a solution that leverages event.stopPropagation(), but couldn't get anything to work. In ActionScript, this kind of thing would be solved by placing a mousewheel handler on the child div that calls stopPropagation() on the event before it reaches the body element. Since JS and AS are both ECMAScript languages, I thought the concept might translate, but it didn't seem to work.

Is there a solution that keeps my page contents from shifting around? Most likely using stopPropagation rather than a CSS fix? JQuery answers are welcome as is pure JS.

like image 878
ericsoco Avatar asked Feb 13 '12 05:02

ericsoco


People also ask

How do I turn off side scrolling?

To hide the horizontal scrollbar and prevent horizontal scrolling, use overflow-x: hidden: HTML. CSS.

How do I restrict scrolling in HTML?

Set overflow-x to hidden to Disable Horizontal Scroll Bar in CSS. We can use the overflow-x property and set it to hidden to disable the horizontal scroll bar in CSS. We can test the disabling of the scroll bar horizontally by limiting a text to only one line.

How do I turn off scroll without hiding?

Apply 'noscroll' to html instead of to body to prevent double scroll bars in IE. To check if there's actually a scroll bar before adding the 'noscroll' class. Otherwise, the site will also jump pushed by the new non-scrolling scroll bar.

How do I disable touch scroll?

Open the Settings app and go to the Devices group of settings. Go to the Touchpad tab. Scroll down to the Zoom and Scroll section, and uncheck the 'Drag two fingers to scroll' option. This will disable scrolling on the touchpad.


2 Answers

here's what i ended up with. very similar to @mrtsherman's answer here, only pure JS events instead of jQuery. i still used jQuery for selecting and moving the child div around, though.

// earlier, i have code that references my child div, as childDiv

function disableWindowScroll () {
    if (window.addEventListener) {
        window.addEventListener("DOMMouseScroll", onChildMouseWheel, false);
    }
    window.onmousewheel = document.onmousewheel = onChildMouseWheel;
}

function enableWindowScroll () {
    if (window.removeEventListener) {
        window.removeEventListener("DOMMouseScroll", onArticleMouseWheel, false);
    }
    window.onmousewheel = document.onmousewheel = null;
}

function onChildMouseWheel (event) {
    var scrollTgt = 0;
    event = window.event || event;
    if (event.detail) {
        scrollTgt = -40 * event.detail;
    } else {
        scrollTgt = event.wheelDeltaY;
    }

    if (scrollTgt) {
        preventDefault(event);
        $(childDiv).scrollTop($(childDiv).scrollTop() - scrollTgt);
    }
}

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

i've noticed the scrolling doesn't match normal scrolling exactly; it seems to scroll a bit faster than without this code. i assume i can fix by knocking down wheelDeltaY a bit, but it's odd that it would be reported differently by javascript than it's actually implemented by the browser...

like image 125
ericsoco Avatar answered Oct 03 '22 07:10

ericsoco


I usually do it with a small hack listening to the scroll event on the document: it resets the scroll height back to the original one - effectively freezing the document from scrolling but any inner element with overflow: auto will still scroll nicely:

var scrollTop = $(document).scrollTop();
$(document).on('scroll.scrollLock', function() {
  $(document).scrollTop(scrollTop);
});

and then when I'm done with the inner scroll lock:

$(document).off('scroll.scrollLock');

the .scrollLock event namespace makes sure I'm not messing with any other event listeners on scroll.

like image 45
stefan Avatar answered Oct 03 '22 08:10

stefan