web-dev-qa-db-ja.com

jQueryは、絶対divの上にマウスがあるときにスクロールを無効にします

マウスがdivの上にホバーしているときにウィンドウのマウススクロール機能を無効にしようとしています-divスクロールのみが有効になっています-そして、マウスがdivから離れると、ウィンドウへのスクロールが再び適用されます。 divは絶対に配置されます。

私はこの投稿を見ました マウスカーソルがdiv内にあるときにjqueryを使用してマウススクロールホイール機能を無効にしますか? しかし、それは答えを提供していないようです-したがって、私の質問です。

私はそれがこのようなものになると仮定しています(これらのメソッドのみが存在した場合):

$('#container').hover(function() {
     $(window).scroll().disable();
     $(this).scroll().enable();
}, function() {
     $(window).scroll().enable();
});
52
user398341

これはよくある質問でしたので、ここで提供される回答の概要を説明するために更新します。 3つの独自のソリューションが含まれています。 2つはAmosから、1つは私からです。ただし、それぞれの動作は異なります。

  1. Amos-セットoverflow:hiddenボディ。これは簡単で、うまく機能します。ただし、メインウィンドウのスクロールバーは点滅します。
  2. Amos-JavaScriptを使用してマウスホイールを無効にします。これは、マウスホイールがまったく必要ない場合に便利です。
  3. この答え-javascriptを使用して、上にある要素のみをスクロールします。これは、内側のdivをスクロールする必要があるが、他のdivをスクロールしたくない場合の最良の答えです。サンプルのフィドルはこれを示しています。

http://jsfiddle.net/eXQf3/371/

コードは次のように機能します。

  • 現在の要素でスクロールイベントをキャッチ
  • スクロールイベントをキャンセルする
  • 現在の要素のみを手動でスクロールします

$('#abs').bind('mousewheel DOMMouseScroll', function(e) {
    var scrollTo = null;

    if (e.type == 'mousewheel') {
        scrollTo = (e.originalEvent.wheelDelta * -1);
    }
    else if (e.type == 'DOMMouseScroll') {
        scrollTo = 40 * e.originalEvent.detail;
    }

    if (scrollTo) {
        e.preventDefault();
        $(this).scrollTop(scrollTo + $(this).scrollTop());
    }
});​

変更ログ:

  • FFサポート
  • scrollTo nullチェックは、予期しないことが発生した場合にデフォルトの動作に戻します
  • jQuery 1.7のサポート。
95
mrtsherman

ウィンドウのスクロールを無効にすることはできませんが、簡単な回避策があります。

//set the overflow to hidden to make scrollbars disappear
$('#container').hover(function() {
    $("body").css("overflow","hidden");
}, function() {
     $("body").css("overflow","auto");
});

デモを参照:http://jsfiddle.net/9Htjw/


[〜#〜] update [〜#〜]

ただし、マウスホイールは無効にできます。

$('#container').hover(function() {
    $(document).bind('mousewheel DOMMouseScroll',function(){ 
        stopWheel(); 
    });
}, function() {
    $(document).unbind('mousewheel DOMMouseScroll');
});


function stopWheel(e){
    if(!e){ /* IE7, IE8, Chrome, Safari */ 
        e = window.event; 
    }
    if(e.preventDefault) { /* Chrome, Safari, Firefox */ 
        e.preventDefault(); 
    } 
    e.returnValue = false; /* IE7, IE8 */
}

出典:http://solidlystated.com/scripting/javascript-disable-mouse-wheel/

デモ:http://jsfiddle.net/9Htjw/4/

31
amosrivera

mrtsherman:このようにイベントをバインドすると、amosriveraのコードはfirefoxでも動作します:

    var elem = document.getElementById ("container");
    if (elem.addEventListener) {    
        elem.addEventListener ("mousewheel", stopWheel, false);
        elem.addEventListener ("DOMMouseScroll", stopWheel, false);
    }
    else {
        if (elem.attachEvent) { 
            elem.attachEvent ("onmousewheel", stopWheel);
        }
    }
3
rocky

@mrtshermanの回答はほとんど役に立ちましたが、 Chromeのパッシブスクロールで重大な変更がありました。

preventScrollingEl = document.getElementById("WHATEVER");
preventScrollingEl.addEventListener('mousewheel', preventScrolling, {passive: false});
preventScrollingEl.addEventListener('DOMMouseScroll', preventScrolling, {passive: false});

function preventScrolling(event) {
  var scrollTo = null;

  if (event.type == 'mousewheel') {
    scrollTo = (event.wheelDelta * -1);
  } else if (event.type == 'DOMMouseScroll') {
    scrollTo = 40 * event.detail;
  }

  if (scrollTo) {
    event.preventDefault();
    $(this).scrollTop(scrollTo + $(this).scrollTop());
  }
}
0
Max Bileschi

私は自分のページでnicescrollを使用しましたが、どのメソッドも機能しませんでした。 nicescrollerがscrollイベントを呼び出していることに気付き、要素をホバーするときにnicescrollを一時的に無効にする必要がありました。

解決策:要素をホバーするときにnicescrollを一時的に無効にします

$('body').on('mouseover', '#element', function() {
    $('body, html').css('overflow', 'auto').getNiceScroll().remove();
}).on('mouseout', '#element', function() {
    $('body, html').css('overflow', 'hidden').niceScroll();
});
0
Lasithds

私のコードでここでやろうとしていることは:

  • Divがホバーまたはマウスオーバーされているかどうかを確認します

  • スクロール方向を取得します

  • ScrollTopをコンテナのHeightと比較し、maxまたはminに達したとき(マウスが外れるまで)さらにスクロールしないようにします。

    var hovered_over = false;
    var hovered_control;          
    function onCrtlMouseEnter(crtl) {      //Had same thing used for mutliple controls 
        hovered_over = true;       //could be replaced with $(control).onmouseenter(); etc
        hovered_control = crtl;    //you name it
    }
    function onCrtlMouseLeave(crtl) {
        hovered_over = false;
        hovered_control = null;
    }
    
    $(document).on("mousewheel",function(e)
    {
       if (hovered_over == true) {                            
            var control = $(hovered_control);                 //get control
            var direction = e.originalEvent.wheelDeltaY;      //get direction of scroll
            if (direction < 0) {
                if ((control.scrollHeight - control.clientHeight) == control.scrollTop) {
                    return false;              //reached max downwards scroll... prevent;
                }
            }
            else if (direction > 0) {
                if (control.scrollTop == 0) {
                    return false;              //reached max upwards scroll... prevent;
                }
            }
        }
    });
    

http://jsfiddle.net/Miotonir/4uw0vra5/1/

おそらく最もクリーンなコードではなく、簡単に改善することができますが、これは私のために機能します。 (control.scrollHeight - control.clientHeight)この部分は私にとってはやや疑わしいですが、とにかく問題に対処する方法のアイデアを得る必要があります。

0
MjolTonir