Как отключить прокрутку во внешних элементах?
У меня есть вертикально-прокручиваемый div внутри страницы, который также прокручивается по вертикали.
Когда дочерний div прокручивается колесом мыши и достигает верхней или нижней части полосы прокрутки, страница (тело) начинает прокручиваться. Пока мышь находится над дочерним div, я бы хотел, чтобы страница (тело) прокручивалась, чтобы быть заблокированной.
Этот пост SO (прокрутка вниз до выбранного ответа) хорошо показывает проблему.
Этот вопрос SO, по сути, такой же, как у меня, но выбранный ответ заставляет мое содержимое страницы заметно смещаться горизонтально, когда полоса прокрутки исчезает и снова появляется.
Я думал, что может быть решение, которое использует event.stopPropagation(), но не может заставить ничего работать. В ActionScript такое решение будет разрешено путем размещения обработчика mousewheel на дочернем div, который вызывает событие stopPropagation() в событии до того, как он достигнет элемента body. Поскольку JS и AS являются языками ECMAScript, я думал, что концепция может быть переведена, но она, похоже, не работает.
Есть ли решение, которое препятствует перемещению содержимого моей страницы? Скорее всего, использование stopPropagation вместо исправления CSS? Ответы JQuery приветствуются, как и чистый JS.
Ответы
Ответ 1
вот что я закончил. очень похоже на @mrtsherman, ответьте здесь, только чистые события 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;
}
Я заметил, что прокрутка не соответствует нормальной прокрутке; он, кажется, прокручивается немного быстрее, чем без этого кода. Я предполагаю, что могу исправить, сбив колесо DeltaY немного, но это странно, что по javascript будет по-разному сообщаться, чем это фактически реализовано браузером...
Ответ 2
Обычно я делаю это с небольшим взломом, слушая событие прокрутки документа: он сбрасывает высоту прокрутки обратно в исходную, - фактически замораживая документ от прокрутки, но любой внутренний элемент с переполнением: авто по-прежнему будет прокручиваться красиво:
var scrollTop = $(document).scrollTop();
$(document).on('scroll.scrollLock', function() {
$(document).scrollTop(scrollTop);
});
а затем, когда я закончил с внутренней блокировкой прокрутки:
$(document).off('scroll.scrollLock');
пространство имен событий .scrollLock гарантирует, что я не буду возиться с другими прослушивателями событий в прокрутке.
Ответ 3
Хотя это старый вопрос, вот как я это делаю с помощью 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>
Ответ 4
что об этом:
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";
};