Подтвердить что ты не робот

Как отключить прокрутку во внешних элементах?

У меня есть вертикально-прокручиваемый div внутри страницы, который также прокручивается по вертикали.

Когда дочерний div прокручивается колесом мыши и достигает верхней или нижней части полосы прокрутки, страница (тело) начинает прокручиваться. Пока мышь находится над дочерним div, я бы хотел, чтобы страница (тело) прокручивалась, чтобы быть заблокированной.

Этот пост SO (прокрутка вниз до выбранного ответа) хорошо показывает проблему.

Этот вопрос SO, по сути, такой же, как у меня, но выбранный ответ заставляет мое содержимое страницы заметно смещаться горизонтально, когда полоса прокрутки исчезает и снова появляется.

Я думал, что может быть решение, которое использует event.stopPropagation(), но не может заставить ничего работать. В ActionScript такое решение будет разрешено путем размещения обработчика mousewheel на дочернем div, который вызывает событие stopPropagation() в событии до того, как он достигнет элемента body. Поскольку JS и AS являются языками ECMAScript, я думал, что концепция может быть переведена, но она, похоже, не работает.

Есть ли решение, которое препятствует перемещению содержимого моей страницы? Скорее всего, использование stopPropagation вместо исправления CSS? Ответы JQuery приветствуются, как и чистый JS.

4b9b3361

Ответ 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";
};