Как отключить прокрутку внешних элементов?
У меня есть div с вертикальной прокруткой внутри страницы, которая также прокручивается по вертикали.
когда дочерний div прокручивается колесиком мыши и достигает верхней или нижней части полосы прокрутки, страница (тело) начинает прокручиваться. Пока мышь находится над дочерним div, я хотел бы, чтобы прокрутка страницы (тела) была заблокирована.
это сообщение SO (прокрутите вниз до выбранного ответа) демонстрирует проблему.
это так вопрос is по сути, то же самое, что и мой, но выбранный ответ заставляет содержимое моей страницы заметно смещаться по горизонтали, когда полоса прокрутки исчезает и появляется.
Я думал, что там может быть решение, которое использует событие.stopPropagation(), но ничего не смог заставить работать. В ActionScript такие проблемы решаются путем размещения обработчика mousewheel на дочернем div, который вызывает stopPropagation () на событии, прежде чем оно достигнет элемента body. Поскольку JS и AS оба ECMAScript языки, я думал, что концепция может перевести, но, похоже, это не сработало.
есть ли решение, которое удерживает содержимое моей страницы от перемещения? Скорее всего, используя stopPropagation, а не исправление CSS? Ответы JQuery приветствуются, как и чистый JS.
4 ответов
вот что я закончил. очень похоже на ответ @mrtsherman's здесь, только чистые события JS вместо jQuery. однако я все еще использовал jQuery для выбора и перемещения ребенка div.
// earlier, i have code that references my child div, as childDiv
function disableWindowScroll () {
if (window.addEventListener) {
window.addEventListener("DOMMouseScroll", onChildMouseWheel, false);
}
window.onmousewheel = document.onmousewheel = onChildMouseWheel;
}
function enableWindowScroll () {
if (window.removeEventListener) {
window.removeEventListener("DOMMouseScroll", onArticleMouseWheel, false);
}
window.onmousewheel = document.onmousewheel = null;
}
function onChildMouseWheel (event) {
var scrollTgt = 0;
event = window.event || event;
if (event.detail) {
scrollTgt = -40 * event.detail;
} else {
scrollTgt = event.wheelDeltaY;
}
if (scrollTgt) {
preventDefault(event);
$(childDiv).scrollTop($(childDiv).scrollTop() - scrollTgt);
}
}
function preventDefault (event) {
event = event || window.event;
if (event.preventDefault) {
event.preventDefault();
}
event.returnValue = false;
}
Я заметил, что прокрутка не соответствует нормальной прокрутке точно; кажется, прокрутка немного быстрее, чем без этого кода. я предполагаю, что могу исправить, сбив wheelDeltaY немного, но странно, что это будет сообщено иначе javascript, чем это фактически реализован браузером...
обычно я делаю это с помощью небольшого Хака, слушающего событие прокрутки в документе: он сбрасывает высоту прокрутки обратно в исходный - эффективно замораживает документ от прокрутки, но любой внутренний элемент с переполнением: auto все равно будет прокручиваться красиво:
var scrollTop = $(document).scrollTop();
$(document).on('scroll.scrollLock', function() {
$(document).scrollTop(scrollTop);
});
а затем, когда я закончу с внутренней блокировкой прокрутки:
$(document).off('scroll.scrollLock');
the .пространство имен событий scrollLock гарантирует, что я не связываюсь с другими прослушивателями событий при прокрутке.
хотя это старый вопрос, вот как я это делаю с jQuery. Это позволяет прокручивать список во внешнем списке, или вы можете изменить внешний список на документ, чтобы сделать то, что попросил OP.
window.scrollLockHolder = null;
function lockScroll(id){
if (window.scrollLockHolder == null){
window.scrollLockHolder = $('#' + id).scrollTop();
}
$('#' + id).on('scroll', function(){
$('#' + id).scrollTop(window.scrollLockHolder);
});
}
function unlockScroll(id){
$('#' + id).off('scroll');
window.scrollLockHolder = null;
}
и вы можете использовать его как это:
<ul onmousemove="lockScroll('outer-scroller-id')" onmouseout="unlockScroll('outer-scroller-id')">
<li>...</li>
<li>...</li>
</ul>
Как насчет этого:
div.onmousemove = function() { // may be onmouseover also works fine
document.body.style.overflow = "hidden";
document.documentElement.style.overflow = "hidden";
};
div.onmouseout = function() {
document.body.style.overflow = "auto";
document.documentElement.style.overflow = "auto";
};