web-dev-qa-db-ja.com

要素からウィンドウへのスクロールバブリングを防ぐ

Iframeを含むモーダルボックスウィンドウ(ポップアップ)があります。
そしてその中にあるiframeスクロール可能なdivがあります。

Iframeの内部DIVをスクロールし、上限または下限に達したとき、
ブラウザ自体のウィンドウがスクロールを開始します。これは望ましくない動作です

私はこのようなものを試しましたが、メインウィンドウのスクロールを殺すとき
onMouseEnterマウスがポップアップボックス領域に入ったとき:

e.preventDefault()は何らかの理由で正常に機能していません...

_$("#popup").mouseenter(function(){
   $(window).bind("scroll", function(e){
        e.preventDefault();
   }); 
}).mouseleave(function(){
    $(window).unbind("scroll");
});
_

更新

2013年の現在のようにe.preventDefault();で十分です...

54
vsync

単純なCSSプロパティを使用して解決しました(modernブラウザー用):
overscroll-behavior

body{
  height: 600px;
  overflow: auto;
}

section{
  width: 50%;
  height: 50%;
  overflow: auto;
  background: lightblue;
  overscroll-behavior: none; /*   <--- the trick    */
}

section::before{
  content: '';
  height: 200%;
  display: block;
}
<section>
 <input value='end' />
</section>

スクロールを「ロックイン」する要素にそのスタイルプロパティを適用するだけで、スクロールイベントは、スクロールを持つ親要素にもバブルアップしません。


上記と同じデモですが、トリックなしで

body{
  height: 600px;
  overflow: auto;
}

section{
  width: 50%;
  height: 50%;
  overflow: auto;
  background: lightblue;
}

section::before{
  content: '';
  height: 200%;
  display: block;
}
<section>
 <input value='end' />
</section>
4
vsync

申し訳ありませんが、私が知る限り、どのような種類のスクロールイベントもキャンセルすることはできません。

W[〜#〜] msdn [〜#〜] の両方:

Cancelable  No
Bubbles     No

これを修正するには、ブラウザーの作成者に任せる必要があると思います。 Firefox(とにかくLinuxの3.5)は私にとってより良い振る舞いをしているようです:あなたがstartスクロールホイールを使用します。

26
bobince

ウィンドウのスクロールを防止できない場合は、元に戻してください。つまり、スクロールイベントをキャッチしてから、スクロールして固定位置に戻します。

次のコードは、$("#popup")の上にカーソルを置く限りY軸をロックします。

// here we store the window scroll position to lock; -1 means unlocked
var forceWindowScrollY = -1;

$(window).scroll(function(event) {
  if(forceWindowScrollY != -1 && window.scrollY != forceWindowScrollY) {
    $(window).scrollTop(forceWindowScrollY);    
  }
});

$("#popup").hover(function() {
  if(forceWindowScrollY == -1) {
    forceWindowScrollY = $(window).scrollTop();
  }
}, function() {
  forceWindowScrollY = -1;
});

http://bundestube.de/ のクエリ候補ボックスにこれを使用します(スクロール可能なペインを表示するには、上部の検索ボックスにいくつかの文字を入力します)。

Screenshot

これは、Chrome/Safari(Webkit)で問題なく動作し、FirefoxおよびOperaでスクロールの不具合が発生します。何らかの理由で、これはmy IEインストールでは機能しません。これは、jQueryのホバーメソッドに関係していると思います。

私のjQueryプラグイン:

$('.child').dontScrollParent();

$.fn.dontScrollParent = function()
{
    this.bind('mousewheel DOMMouseScroll',function(e)
    {
        var delta = e.originalEvent.wheelDelta || -e.originalEvent.detail;

        if (delta > 0 && $(this).scrollTop() <= 0)
            return false;
        if (delta < 0 && $(this).scrollTop() >= this.scrollHeight - $(this).height())
            return false;

        return true;
    });
}
3
psycho brm

私はそれがかなり古い質問であることを知っていますが、これはGoogleのトップの結果の1つであるため... jQueryなしでスクロールバブリングを何らかの形でキャンセルする必要があり、このコードは私のために機能します:

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

document.getElementById('a').onmousewheel = function(e) { 
  document.getElementById('a').scrollTop -= e. wheelDeltaY; 
  preventDefault(e);
}
3
Nebril

それが私が問題を解決した方法です:

ポップアップを開いたときに次を呼び出します。

$('body').css('overflow','hidden');

次に、ポップアップを閉じるときにこれを呼び出します:

$('body').css('overflow','auto');

ポップアップはモーダルであるため、下にあるボディとの対話は不要です。

かなりうまくいく

1

どうやら、 overflow:hiddenスクロールを防ぎます 。ドキュメントが既にスクロールされている場合、それがどうなるかわかりません。私はマウスレスのラップトップも使っているので、今夜はスクロールホイールのテストはしません:-).

0
Dan F

ここに私がやることがあります:

  $('.noscroll').on('DOMMouseScroll mousewheel', function(ev) {
     var prevent = function() {
         ev.stopPropagation();
         ev.preventDefault();
         ev.returnValue = false;
         return false;
     }
     return prevent();
  }); 

デモフィドル

CSSを使用overflow:hiddenスクロールバーを非表示にします。これにより、スクロールバーはドラッグしても何もしません。

Worksクロスブラウザ

0
parliament

最適に動作することがわかった、少し更新されたコードを追加したいと思います。

var yourElement = $('.my-element');

yourElement.on('scroll mousewheel wheel DOMMouseScroll', function (e) {
    var delta = e.originalEvent.wheelDelta || -e.originalEvent.detail;

    if (delta > 0 && $(this).scrollTop() <= 0)
        return false;
    if (delta < 0 && $(this).scrollTop() >= this.scrollHeight - $(this).outerHeight())
        return false;

    return true;
});

これと既に上で述べたものとの違いは、イベントの追加とheight()の代わりにouterHeight()を使用することです。パディング!

0

新しいWeb開発者はこちら。これは、IEとChromeの両方で魅力的でした。

static preventScrollPropagation(e: HTMLElement) {
    e.onmousewheel = (ev) => {
        var preventScroll = false;
        var isScrollingDown = ev.wheelDelta < 0;
        if (isScrollingDown) {
            var isAtBottom = e.scrollTop + e.clientHeight == e.scrollHeight;
            if (isAtBottom) {
                preventScroll = true;
            }
        } else {
            var isAtTop = e.scrollTop == 0;
            if (isAtTop) {
                preventScroll = true;
            }
        }
        if (preventScroll) {
            ev.preventDefault();
        }
    }
}

行の数に惑わされないでください、それは非常に簡単です-読みやすさのためにほんの少し冗長です(自己記録コードは正しいですか?)

0
Vivek Maharajh

iframe内でjscrollペインを試して、デフォルトのスクロールを置き換えることができます。

http://www.kelvinluck.com/assets/jquery/jScrollPane/jScrollPane.html

よくわかりませんが、試してみてください

0
adardesign

2018年以降、e.preventDefaultで十分です。

$('.elementClass').on("scroll", function(e){
    e.preventDefault();
 }); 

これにより、親へのスクロールが防止されます。

0
Asif J
$('.scrollable').on('DOMMouseScroll mousewheel', function (e) {
    var up = false;
    if (e.originalEvent) {
        if (e.originalEvent.wheelDelta) up = e.originalEvent.wheelDelta / -1 < 0;
        if (e.originalEvent.deltaY) up = e.originalEvent.deltaY < 0;
        if (e.originalEvent.detail) up = e.originalEvent.detail < 0;
    }

    var prevent = function () {
        e.stopPropagation();
        e.preventDefault();
        e.returnValue = false;
        return false;
    }

    if (!up && this.scrollHeight <= $(this).innerHeight() + this.scrollTop + 1) {
        return prevent();
    } else if (up && 0 >= this.scrollTop - 1) {
        return prevent();
    }
});
0
Roland Soós