Ich habe ein Div mit einer Bildlaufleiste. Wenn es das Ende erreicht, beginnt meine Seite zu scrollen. Kann ich dieses Verhalten trotzdem stoppen?
Ich habe ein Div mit einer Bildlaufleiste. Wenn es das Ende erreicht, beginnt meine Seite zu scrollen. Kann ich dieses Verhalten trotzdem stoppen?
Antworten:
Sie können das Scrollen der gesamten Seite inaktivieren, indem Sie Folgendes tun:
<div onmouseover="document.body.style.overflow='hidden';" onmouseout="document.body.style.overflow='auto';"></div>
Die Lösung gefunden.
Das brauchte ich.
Und das ist der Code.
http://jsbin.com/itajok/edit#javascript,html
Verwendet ein jQuery-Plug-In.
Update wegen Verfallserklärung
Vom jquery-mousewheel :
Das alte Verhalten der Zugabe von drei Argumente (
delta,deltaX, unddeltaY) an den Ereignishandler ist jetzt veraltet und wird in späteren Versionen entfernt werden.
Dann event.deltaYmuss jetzt verwendet werden:
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;
});
Die ausgewählte Lösung ist ein Kunstwerk. Ich dachte, es wäre ein Plugin wert ...
$.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();
});
};
Dies war für mich eine ständige Unannehmlichkeit und diese Lösung ist im Vergleich zu anderen Hacks, die ich gesehen habe, so sauber. Neugierig zu wissen, wie viel mehr darüber funktioniert und wie weit verbreitet es sein würde, aber ein Hoch auf Jeevan und jeden, der sich das ursprünglich ausgedacht hat. Übrigens - der Stackoverflow-Antworteditor benötigt dies!
AKTUALISIEREN
Ich glaube, das ist insofern besser, als es nicht versucht, das DOM überhaupt zu manipulieren, sondern nur das bedingte Sprudeln verhindert ...
$.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);
}
})
;
};
Funktioniert hervorragend in Chrom und ist viel einfacher als andere Lösungen ... lassen Sie mich wissen, wie es anderswo abschneidet ...
Sie könnten ein Mouseover-Ereignis auf dem div verwenden, um die Body-Bildlaufleiste zu deaktivieren, und dann ein Mouseout-Ereignis, um sie erneut zu aktivieren?
ZB das HTML
<div onmouseover="disableBodyScroll();" onmouseout="enableBodyScroll();">
content
</div>
Und dann gefällt das Javascript so:
var body = document.getElementsByTagName('body')[0];
function disableBodyScroll() {
body.style.overflowY = 'hidden';
}
function enableBodyScroll() {
body.style.overflowY = 'auto';
}
document.bodystattdessen auch verwenden.
Hier ist eine browserübergreifende Methode, um dies auf der Y-Achse zu tun. Sie funktioniert auf Desktop- und Mobilgeräten. Getestet unter OSX und 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 durch scrollTop >= maxScroll. Es scheint seltsam zu sein, in einem Fall wurde es benötigt
Ich habe eine Lösung für dieses Problem geschrieben
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.
falsejedoch nicht angegeben werden, addEventListenerda dies die Standardeinstellung ist. Darüber hinaus sollten die Vergleiche einfache Ungleichungen ( >und <) sein, nicht >=oder <=.
Wenn ich Ihre Frage richtig verstehe, möchten Sie verhindern, dass der Hauptinhalt gescrollt wird, wenn sich die Maus über einem Div befindet (sagen wir eine Seitenleiste). Aus diesem Grund ist die Seitenleiste möglicherweise kein untergeordnetes Element des Bildlaufcontainers des Hauptinhalts (der das Browserfenster war), um zu verhindern, dass das Bildlaufereignis zu seinem übergeordneten Element sprudelt.
Dies erfordert möglicherweise einige Markup-Änderungen auf folgende Weise:
<div id="wrapper">
<div id="content">
</div>
</div>
<div id="sidebar">
</div>
Sehen Sie, dass es in dieser Beispielgeige funktioniert, und vergleichen Sie dies mit dieser Beispielgeige, die ein etwas anderes Mausverlaufsverhalten der Seitenleiste aufweist.
Siehe auch nur einen bestimmten Div mit der Hauptscrollleiste des Browsers scrollen .
Wie hier beantwortet , unterstützen die meisten modernen Browser jetzt die overscroll-behavior: none;CSS-Eigenschaft, die eine Bildlaufverkettung verhindert. Und das war's, nur eine Zeile!
overscroll-behavior: contain;.
Dadurch wird das Scrollen im Fenster deaktiviert, wenn Sie das Auswahlelement eingeben. funktioniert wie Zauber.
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");
});
Sie können das Scrollen der gesamten Seite inaktivieren, indem Sie so etwas tun, aber die Bildlaufleiste anzeigen!
<div onmouseover="document.body.style.overflow='hidden'; document.body.style.position='fixed';" onmouseout="document.body.style.overflow='auto'; document.body.style.position='relative';"></div>
$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();
}
});
Basierend auf der Antwort von ceed ist hier eine Version, die das Verschachteln von scrollgeschützten Elementen ermöglicht. Nur das Element, über dem sich die Maus befindet, wird gescrollt, und es wird ganz reibungslos gescrollt. Diese Version ist ebenfalls wieder verfügbar. Es kann mehrfach für dasselbe Element verwendet werden und entfernt und behandelt die Handler korrekt.
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");
});
};
Eine einfache Möglichkeit besteht darin scroll-guard, allen Elementen auf der Seite, auf denen Sie einen Bildlauf durchführen können , eine Klasse hinzuzufügen, z . Dann verwenden Sie $('.scroll-guard').scrollGuard(), um sie zu schützen.
Wenn Sie einen overflow: hiddenStil anwenden , sollte er verschwinden
edit: eigentlich habe ich deine frage falsch gelesen, das wird nur die scrollleiste verbergen, aber ich glaube nicht, dass du danach suchst.
Ich konnte keine der Antworten für die Arbeit in Chrome und Firefox erhalten, daher habe ich mir diese Zusammenführung ausgedacht:
$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;
}
}
}