У меня есть div с полосой прокрутки. Когда он доходит до конца, моя страница начинает прокручиваться. Как я могу остановить такое поведение?
У меня есть div с полосой прокрутки. Когда он доходит до конца, моя страница начинает прокручиваться. Как я могу остановить такое поведение?
Ответы:
Вы можете отключить прокрутку всей страницы, сделав что-то вроде этого:
<div onmouseover="document.body.style.overflow='hidden';" onmouseout="document.body.style.overflow='auto';"></div>
Нашел решение.
Это то, что мне было нужно.
А это код.
http://jsbin.com/itajok/edit#javascript,html
Использует подключаемый модуль jQuery.
Обновление в связи с уведомлением о прекращении поддержки
Из jquery-mousewheel :
Старое поведение добавления трех аргументов (
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();
});
};
Это доставляло мне постоянные неудобства, и это решение настолько чистое по сравнению с другими хаками, которые я видел. Любопытно узнать, как еще это работает и насколько широко это будет поддержано, но приветствую Дживана и тех, кто изначально это придумал. Кстати, это нужно редактору ответов 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);
}
})
;
};
Отлично работает в Chrome и намного проще, чем другие решения ... дайте мне знать, как это работает в других местах ...
wheel
событие
Вы можете использовать событие mouseover в div, чтобы отключить полосу прокрутки тела, а затем событие 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
by 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
поскольку это значение по умолчанию. Причем сравнения должны быть простыми неравенствами ( >
и <
), а не >=
или <=
.
Как здесь сказано , большинство современных браузеров теперь поддерживают overscroll-behavior: none;
свойство CSS, которое предотвращает цепочку прокрутки. И все, всего одна строчка!
overscroll-behavior: contain;
.
Если я правильно понимаю ваш вопрос, вы хотите предотвратить прокрутку основного содержимого, когда указатель мыши находится над div (скажем, боковой панелью). Для этого боковая панель может не быть дочерним элементом контейнера прокрутки основного содержимого (которым было окно браузера), чтобы предотвратить всплытие события прокрутки до его родительского элемента.
Возможно, это потребует некоторых изменений разметки следующим образом:
<div id="wrapper">
<div id="content">
</div>
</div>
<div id="sidebar">
</div>
Посмотрите, как он работает в этом образце скрипки, и сравните его с этим образцом скрипта, который имеет несколько иное поведение боковой панели при отпускании мыши.
См. Также прокрутку только одного конкретного div с помощью основной полосы прокрутки браузера .
это отключает прокрутку в окне, если вы вводите элемент селектора. работает как чары.
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");
});
Вы можете отключить прокрутку всей страницы, сделав что-то вроде этого, но отобразить полосу прокрутки!
<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();
}
});
Основываясь на ответе 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");
});
};
Один из простых способов использования - добавить класс, например 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;
}
}
}