Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
398 views
in Technique[技术] by (71.8m points)

javascript - 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.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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...


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...