Сам неделю назад решал подобную проблему, когда необходим был скролл внутри кастомного попапа, с блокировкой скролла самой страницы. Оказалось, что если вариант с overflow: hidden; не подходит по эстетическим соображениям из-за моментально меняющей ширины страницы (пропажа скроллбара), то придется пилить велосипед. Тут реализована блокировка скролла, которая позволяет скроллить внутри контейнера, если в направлении скролла есть чего еще скроллить. То есть если убрать строчки с st > 0 (и подобной для конца скролла) , то глобальная страница будет скроллится, когда скролл попапа будет доходить до конца/начала. Ну а $(e.target).closest(popUpClass).length соответственно проверяет, находитесь ли вы внутри попАпа в общем плане, чтобы не блокировался весь скролл вообще. Ах да, тут еще блокируются клавиши для скроллинга, кроме пробела, чтобы в инпутах печатать можно было.
Получилось примерно такое:
var scrollKeys = [33,34,35,36,38,40];
var popUpClass = ".%класс-активного-попАпа%";
function preventScroll() {
$(document).on("mousewheel DOMMouseScroll", "body", function(e) {
var $np = $(popUpClass)[0];
var st = $np.scrollTop;
if (e.originalEvent.wheelDelta > 0 || e.originalEvent.detail < 0) {
if ($(e.target).closest(popUpClass).length &&
st > 0) return;
} else {
if ($(e.target).closest(popUpClass).length &&
st + $np.offsetHeight < $np.scrollHeight) return;
}
e.preventDefault();
e.stopPropagation();
});
$(document).on("keydown", function(e) {
if (scrollKeys.indexOf(e.which) > -1) {
e.preventDefault();
}
});
};
function returnScroll() {
$(document).off("mousewheel DOMMouseScroll keydown");
};
// если необходимо делегирование событий, замените на mouseenter и mouseleave соответственно
$(popUpClass).hover(function() {
preventScroll();
}, function() {
returnScroll();
});