Mam element DIV z paskiem przewijania. Kiedy dojdzie do końca, moja strona zaczyna się przewijać. Czy w ogóle mogę powstrzymać to zachowanie?
javascript
html
Jeevan
źródło
źródło
Odpowiedzi:
Możesz wyłączyć przewijanie całej strony, wykonując coś takiego:
<div onmouseover="document.body.style.overflow='hidden';" onmouseout="document.body.style.overflow='auto';"></div>
źródło
Znalazłem rozwiązanie.
http://jsbin.com/itajok
To jest to, czego potrzebowałem.
A to jest kod.
http://jsbin.com/itajok/edit#javascript,html
Używa wtyczki jQuery.
Aktualizacja z powodu powiadomienia o wycofaniu
Z jquery-mousewheel :
Następnie
event.deltaY
należy teraz użyć: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; });
Próbny
źródło
Wybrane rozwiązanie to dzieło sztuki. Pomyślałem, że zasługuje na wtyczkę ...
$.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(); }); };
Jest to dla mnie ciągła niedogodność, a to rozwiązanie jest tak czyste w porównaniu z innymi hackami, które widziałem. Ciekawe, jak więcej o tym, jak to działa i jak szeroko byłoby to wspierane, ale wiwatuje Jeevanowi i temu, kto to wymyślił. BTW - edytor odpowiedzi stackoverflow tego potrzebuje!
AKTUALIZACJA
Uważam, że jest to lepsze, ponieważ w ogóle nie próbuje manipulować DOM, a jedynie zapobiega warunkowemu bulgotaniu ...
$.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); } }) ; };
Świetnie sprawdza się w chrome i dużo prostszy niż inne rozwiązania ... daj mi znać, jak gdzie indziej wypada ...
SKRZYPCE
źródło
wheel
wydarzenieMożesz użyć zdarzenia mouseover na div, aby wyłączyć pasek przewijania treści, a następnie zdarzenia mouseout, aby go ponownie aktywować?
Np. HTML
<div onmouseover="disableBodyScroll();" onmouseout="enableBodyScroll();"> content </div>
A potem javascript w ten sposób:
var body = document.getElementsByTagName('body')[0]; function disableBodyScroll() { body.style.overflowY = 'hidden'; } function enableBodyScroll() { body.style.overflowY = 'auto'; }
źródło
document.body
zamiast tego.Oto sposób na zrobienie tego na osi Y w różnych przeglądarkach, działa na komputerach stacjonarnych i urządzeniach mobilnych. Przetestowano na OSX i 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});
źródło
scrollTop === maxScroll
przezscrollTop >= maxScroll
. Wydaje się to dziwne w 1 przypadku, było potrzebneNapisałem rozwiązanie tego problemu
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);
źródło
e.currentTarget
.false
nie trzeba go określać,addEventListener
ponieważ jest to ustawienie domyślne. Ponadto porównania powinny być prostymi nierównościami (>
i<
), a nie>=
lub<=
.Jak tu udzielono odpowiedzi , większość nowoczesnych przeglądarek obsługuje teraz
overscroll-behavior: none;
właściwość CSS, która zapobiega tworzeniu łańcuchów przewijania. I to wszystko, tylko jedna linijka!źródło
overscroll-behavior: contain;
.Jeśli dobrze rozumiem twoje pytanie, chcesz zapobiec przewijaniu głównej treści, gdy wskaźnik myszy znajduje się nad elementem div (powiedzmy, pasek boczny). W tym celu pasek boczny może nie być elementem podrzędnym kontenera przewijania głównej zawartości (którym było okno przeglądarki), aby zapobiec pojawieniu się zdarzenia przewijania do jego elementu nadrzędnego.
Może to wymagać pewnych zmian w znacznikach w następujący sposób:
<div id="wrapper"> <div id="content"> </div> </div> <div id="sidebar"> </div>
Zobacz, jak działa na tych przykładowych skrzypcach i porównaj to z tymi przykładowymi skrzypcami które ma nieco inne zachowanie paska bocznego przy opuszczaniu myszy.
Zobacz także przewijanie tylko jednego określonego elementu div za pomocą głównego paska przewijania przeglądarki .
źródło
wyłącza to przewijanie w oknie, jeśli wejdziesz do elementu selektora. działa jak urok.
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"); });
źródło
Możesz wyłączyć przewijanie całej strony, wykonując coś takiego, ale wyświetlając pasek przewijania!
<div onmouseover="document.body.style.overflow='hidden'; document.body.style.position='fixed';" onmouseout="document.body.style.overflow='auto'; document.body.style.position='relative';"></div>
źródło
$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(); } });
źródło
W oparciu o odpowiedź Ceeda, oto wersja, która pozwala na zagnieżdżanie chronionych elementów przewijania. Tylko element, nad którym znajduje się mysz, będzie się przewijał i przewija się całkiem płynnie. Ta wersja jest również ponownie wprowadzana. Może być używany wiele razy na tym samym elemencie i poprawnie usunie i ponownie zainstaluje uchwyty.
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"); }); };
Jednym prostym sposobem użycia jest dodanie klasy, na przykład
scroll-guard
, do wszystkich elementów na stronie, na których możesz przewijać. Następnie użyj,$('.scroll-guard').scrollGuard()
aby ich chronić.źródło
Jeśli zastosujesz
overflow: hidden
styl, powinien zniknąćedycja: właściwie źle odczytałem twoje pytanie, to tylko ukryje pasek przewijania, ale nie sądzę, że tego szukasz.
źródło
Nie mogłem uzyskać żadnej odpowiedzi do pracy w Chrome i Firefox, więc wymyśliłem to połączenie:
$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; } } }
źródło