スクロールバー付きのdivがあり、最後に達するとページがスクロールし始めます。とにかく私はこの行動を止めることができますか?
スクロールバー付きのdivがあり、最後に達するとページがスクロールし始めます。とにかく私はこの行動を止めることができますか?
回答:
次のようにして、ページ全体のスクロールを無効にすることができます。
<div onmouseover="document.body.style.overflow='hidden';" onmouseout="document.body.style.overflow='auto';"></div>
解決策を見つけました。
これが私が必要としたものです。
そして、これがコードです。
http://jsbin.com/itajok/edit#javascript,html
jQueryプラグインを使用します。
廃止の通知による更新
三つの引数(追加の以前の動作
delta、deltaXおよびdeltaYイベントハンドラには)廃止されて以降のリリースでは削除されます。
次に、event.deltaY使用する必要があります:
var toolbox = $('#toolbox'),
height = toolbox.height(),
scrollHeight = toolbox.get(0).scrollHeight;
toolbox.off("mousewheel").on("mousewheel", function (event) {
var blockScrolling = this.scrollTop === scrollHeight - height && event.deltaY < 0 || this.scrollTop === 0 && event.deltaY > 0;
return !blockScrolling;
});
選択されたソリューションは芸術作品です。それはプラグインの価値があると思った....
$.fn.scrollGuard = function() {
return this
.on( 'wheel', function ( e ) {
var event = e.originalEvent;
var d = event.wheelDelta || -event.detail;
this.scrollTop += ( d < 0 ? 1 : -1 ) * 30;
e.preventDefault();
});
};
これは私にとって継続的な不便であり、このソリューションは私が見た他のハックと比べてとてもクリーンです。それがどのように機能するか、そしてそれがどれほど広くサポートされるかについて知りたいと思っていますが、Jeevanと最初にこれを思いついた人は誰でも乾杯します。ところで-stackoverflow回答エディターにはこれが必要です!
更新
私はこれがDOMをまったく操作しようとせず、条件付きでバブリングするのを防ぐだけで良いと思います...
$.fn.scrollGuard2 = function() {
return this
.on( 'wheel', function ( e ) {
var $this = $(this);
if (e.originalEvent.deltaY < 0) {
/* scrolling up */
return ($this.scrollTop() > 0);
} else {
/* scrolling down */
return ($this.scrollTop() + $this.innerHeight() < $this[0].scrollHeight);
}
})
;
};
クロムで動作し、他のソリューションよりもはるかに単純です...他の場所での価格を教えてください...
divでmouseoverイベントを使用して本体のスクロールバーを無効にしてから、mouseoutイベントを使用して再度アクティブ化できますか?
例えば、HTML
<div onmouseover="disableBodyScroll();" onmouseout="enableBodyScroll();">
content
</div>
そして、次のようなJavaScript:
var body = document.getElementsByTagName('body')[0];
function disableBodyScroll() {
body.style.overflowY = 'hidden';
}
function enableBodyScroll() {
body.style.overflowY = 'auto';
}
document.body代わりに使用することもできます。
これはY軸でこれを行うためのクロスブラウザーの方法です。デスクトップとモバイルで機能します。OSXおよびiOSでテスト済み。
var scrollArea = this.querySelector(".scroll-area");
scrollArea.addEventListener("wheel", function() {
var scrollTop = this.scrollTop;
var maxScroll = this.scrollHeight - this.offsetHeight;
var deltaY = event.deltaY;
if ( (scrollTop >= maxScroll && deltaY > 0) || (scrollTop === 0 && deltaY < 0) ) {
event.preventDefault();
}
}, {passive:false});
scrollArea.addEventListener("touchstart", function(event) {
this.previousClientY = event.touches[0].clientY;
}, {passive:false});
scrollArea.addEventListener("touchmove", function(event) {
var scrollTop = this.scrollTop;
var maxScroll = this.scrollHeight - this.offsetHeight;
var currentClientY = event.touches[0].clientY;
var deltaY = this.previousClientY - currentClientY;
if ( (scrollTop >= maxScroll && deltaY > 0) || (scrollTop === 0 && deltaY < 0) ) {
event.preventDefault();
}
this.previousClientY = currentClientY;
}, {passive:false});
scrollTop === maxScroll ではscrollTop >= maxScroll。1つのケースでは奇妙なようで、必要でした
この問題の解決策を書いた
var div;
div = document.getElementsByClassName('selector')[0];
div.addEventListener('mousewheel', function(e) {
if (div.clientHeight + div.scrollTop + e.deltaY >= div.scrollHeight) {
e.preventDefault();
div.scrollTop = div.scrollHeight;
} else if (div.scrollTop + e.deltaY <= 0) {
e.preventDefault();
div.scrollTop = 0;
}
}, false);
e.currentTarget。
falseはaddEventListenerデフォルトであるため、を指定する必要はありません。また、比較は簡単な不等式(あるべきである>と<)、しません>=か、<=。
私があなたの質問を正しく理解した場合、マウスがdiv(サイドバーとしましょう)の上にあるときにメインコンテンツがスクロールしないようにする必要があります。そのため、スクロールイベントがその親にバブリングしないように、サイドバーはメインコンテンツのスクロールコンテナー(ブラウザーウィンドウでした)の子ではない場合があります。
これには、おそらく次の方法でいくつかのマークアップ変更が必要です。
<div id="wrapper">
<div id="content">
</div>
</div>
<div id="sidebar">
</div>
それはで働いて参照してください。このサンプルフィドルとしていることを比較し、このサンプルフィドル、サイドバーのわずかに異なるマウス休暇挙動を有します。
ブラウザのメインスクロールバーで特定のdivのみをスクロールすることもご覧ください。
これにより、selector要素を入力した場合、ウィンドウのスクロールが無効になります。チャームのように機能します。
elements = $(".selector");
elements.on('mouseenter', function() {
window.currentScrollTop = $(window).scrollTop();
window.currentScrollLeft = $(window).scrollTop();
$(window).on("scroll.prevent", function() {
$(window).scrollTop(window.currentScrollTop);
$(window).scrollLeft(window.currentScrollLeft);
});
});
elements.on('mouseleave', function() {
$(window).off("scroll.prevent");
});
$this.find('.scrollingDiv').on('mousewheel DOMMouseScroll', function (e) {
var delta = -e.originalEvent.wheelDelta || e.originalEvent.detail;
var scrollTop = this.scrollTop;
if((delta < 0 && scrollTop === 0) || (delta > 0 && this.scrollHeight - this.clientHeight - scrollTop === 0)) {
e.preventDefault();
}
});
ceedの回答に基づいて、スクロールガードされた要素をネストできるバージョンを次に示します。マウスが置かれた要素のみがスクロールし、スムーズにスクロールします。このバージョンも再入可能です。同じ要素で複数回使用でき、ハンドラーを正しく削除して再インストールします。
jQuery.fn.scrollGuard = function() {
this
.addClass('scroll-guarding')
.off('.scrollGuard').on('mouseenter.scrollGuard', function() {
var $g = $(this).parent().closest('.scroll-guarding');
$g = $g.length ? $g : $(window);
$g[0].myCst = $g.scrollTop();
$g[0].myCsl = $g.scrollLeft();
$g.off("scroll.prevent").on("scroll.prevent", function() {
$g.scrollTop($g[0].myCst);
$g.scrollLeft($g[0].myCsl);
});
})
.on('mouseleave.scrollGuard', function() {
var $g = $(this).parent().closest('.scroll-guarding');
$g = $g.length ? $g : $(window);
$g.off("scroll.prevent");
});
};
使用する簡単な方法の1つはscroll-guard、スクロール可能なページのすべての要素になどのクラスを追加することです。次に、$('.scroll-guard').scrollGuard()それらを保護するために使用します。
overflow: hiddenスタイルを適用すると、それは消えるはずです
編集:実際には私はあなたの質問を間違って読みました、それはスクロールバーを隠すだけですが、あなたが探しているものではないと思います。
ChromeとFirefoxで動作するように答えを得ることができなかったので、この合併を思いつきました。
$someElement.on('mousewheel DOMMouseScroll', scrollProtection);
function scrollProtection(event) {
var $this = $(this);
event = event.originalEvent;
var direction = (event.wheelDelta * -1) || (event.detail);
if (direction < 0) {
if ($this.scrollTop() <= 0) {
return false;
}
} else {
if ($this.scrollTop() + $this.innerHeight() >= $this[0].scrollHeight) {
return false;
}
}
}