16

ページ内に垂直方向にスクロールするdivがあり、これも垂直方向にスクロールします。

子divがマウスホイールでスクロールされ、スクロールバーの上部または下部に到達すると、ページ(本文)がスクロールを開始します。マウスが子divの上にある間、ページ(本文)のスクロールをロックしたいのですが。

このSO投稿(選択した回答までスクロールダウン)は、問題をよく示しています。

このSOの質問は基本的に私のものと同じですが、選択した回答により、スクロールバーが消えて再び表示されるため、ページのコンテンツが水平方向に著しくシフトします。

event.stopPropagation()を活用するソリューションがあるかもしれないと思いましたが、何も機能しませんでした。ActionScriptでは、この種の問題は、body要素に到達する前にイベントでstopPropagation()を呼び出す子divにマウスホイールハンドラーを配置することで解決されます。JSとASはどちらもECMAScript言語なので、概念は翻訳されるかもしれないと思いましたが、うまくいかなかったようです。

ページのコンテンツが移動しないようにするソリューションはありますか?CSS修正ではなくstopPropagationを使用している可能性が高いですか?純粋なJSと同様に、JQueryの回答は大歓迎です。

4

4 に答える 4

4

これが私が最終的に得たものです。ここでの@mrtshermanの回答と非常によく似ていますが、jQueryではなく純粋なJSイベントのみです。ただし、子divを選択して移動するためにjQueryを使用しました。

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

于 2012-02-13T07:13:12.883 に答える
1

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.

于 2014-05-15T10:41:49.453 に答える
0

Although this is an old question, here is how I do it with jQuery. This allows you to scroll a list within an outer list, or you can change the outer list to the document to do what the OP asked.

window.scrollLockHolder = null;
function lockScroll(id){
    if (window.scrollLockHolder == null){
        window.scrollLockHolder = $('#' + id).scrollTop();
    }
    $('#' + id).on('scroll', function(){
        $('#' + id).scrollTop(window.scrollLockHolder);
    });
}
function unlockScroll(id){
    $('#' + id).off('scroll');
    window.scrollLockHolder = null;
}

And you can use it like this:

<ul onmousemove="lockScroll('outer-scroller-id')" onmouseout="unlockScroll('outer-scroller-id')">
    <li>...</li>
    <li>...</li>
</ul>
于 2016-12-05T22:45:12.620 に答える
-2

これはどうですか:

div.onmousemove = function() { // may be onmouseover also works fine
    document.body.style.overflow = "hidden";
    document.documentElement.style.overflow = "hidden";
};

div.onmouseout = function() {
    document.body.style.overflow = "auto";
    document.documentElement.style.overflow = "auto";
};
于 2012-02-13T06:46:05.233 に答える