Как отключить прокрутку во внешних элементах? - PullRequest
15 голосов
/ 13 февраля 2012

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

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

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

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

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

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

Ответы [ 4 ]

4 голосов
/ 13 февраля 2012

вот что я закончил. очень похоже на ответ @ 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;
}

Я заметил, что прокрутка точно не соответствует обычной прокрутке; кажется, что прокрутка немного быстрее, чем без этого кода. я предполагаю, что могу исправить, немного сбив wheelDeltaY, но странно, что в javascript об этом будет сообщаться иначе, чем в действительности реализовано браузером ...

1 голос
/ 15 мая 2014

Я обычно делаю это с небольшим хаком, слушая событие прокрутки в документе: он сбрасывает высоту прокрутки обратно к исходной - эффективно замораживая документ от прокрутки, но любой внутренний элемент с переполнением: auto все равно будет хорошо прокручиваться

var scrollTop = $(document).scrollTop();
$(document).on('scroll.scrollLock', function() {
  $(document).scrollTop(scrollTop);
});

, а затем, когда я закончу с внутренней блокировкой прокрутки:

$(document).off('scroll.scrollLock');

пространство имен события .scrollLock гарантирует, что я не буду связываться с другими слушателями событий при прокрутке.

0 голосов
/ 06 декабря 2016

Хотя это старый вопрос, вот как я это делаю с 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>
0 голосов
/ 13 февраля 2012

что по этому поводу:

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";
};
...