Я хочу, чтобы мое тело перестало прокручиваться при использовании колесика мыши, в то время как Модаль (от http://twitter.github.com/bootstrap) открыт на моем сайте.
Я попытался вызвать кусок javascript ниже, когда модаль открыт, но без успеха
$(window).scroll(function() { return false; });
AND
$(window).live('scroll', function() { return false; });
Обратите внимание, что наш сайт потерял поддержку IE6, но IE7 + должен быть совместим.
Ответ 1
Bootstrap modal
автоматически добавляет класс modal-open
в тело, когда отображается модальное диалоговое окно, и удаляет его, когда диалог скрыт. Поэтому вы можете добавить следующее в свой CSS:
body.modal-open {
overflow: hidden;
}
Вы можете утверждать, что приведенный выше код относится к базе кода CSS Bootstrap, но это легко исправить, чтобы добавить его на ваш сайт.
Обновление 8 февраля 2013 года
Это теперь перестало работать в Twitter Boostrap v. 2.3.0 - они больше не добавляют класс modal-open
к телу.
Обходной путь состоял в том, чтобы добавить класс в тело, когда модальный объект будет показан, и удалите его, когда модаль закрыт:
$("#myModal").on("show", function () {
$("body").addClass("modal-open");
}).on("hidden", function () {
$("body").removeClass("modal-open")
});
Обновление 11 марта 2013 года
Похоже, класс modal-open
вернется в Bootstrap 3.0, явно для предотвращения прокрутки:
Повторно вводит .modal-open на тело (чтобы мы могли прокрутить там свиток)
Смотрите это: https://github.com/twitter/bootstrap/pull/6342 - посмотрите раздел Модальный.
Ответ 2
Принятый ответ не работает на мобильных устройствах (iOS 7 w/Safari 7, по крайней мере), и я не хочу, чтобы на моем сайте выполнялся JavaScript MOAR, когда CSS будет делать.
Этот CSS предотвратит прокрутку фоновой страницы под модальным:
body.modal-open {
overflow: hidden;
position: fixed;
}
Однако, он также имеет небольшое побочное воздействие, существенно зависящее от вершины. position:absolute
разрешает это, но повторно вводит возможность прокрутки на мобильном устройстве.
Если вы знаете свой viewport (мой плагин для добавления области просмотра в <body>
), вы можете просто добавить css-переключатель для position
.
body.modal-open {
// block scroll for mobile;
// causes underlying page to jump to top;
// prevents scrolling on all screens
overflow: hidden;
position: fixed;
}
body.viewport-lg {
// block scroll for desktop;
// will not jump to top;
// will not prevent scroll on mobile
position: absolute;
}
Я также добавляю это, чтобы препятствовать тому, чтобы нижняя страница прыгала влево/вправо при отображении/скрытии модалов.
body {
// STOP MOVING AROUND!
overflow-x: hidden;
overflow-y: scroll !important;
}
этот ответ является x-post.
Ответ 3
Просто скройте переполнение корпуса и сделайте тело не прокруткой. Когда вы скрываете модальный, верните его в автоматический режим.
Вот код:
$('#adminModal').modal().on('shown', function(){
$('body').css('overflow', 'hidden');
}).on('hidden', function(){
$('body').css('overflow', 'auto');
})
Ответ 4
Вы можете попробовать установить размер тела на размер окна с переполнением: скрытый, когда модальный открыт
Ответ 5
Предупреждение:. Параметр ниже не относится к Bootstrap v3.0.x, поскольку прокрутка в этих версиях явно ограничивается самим модалом. Если вы отключите события колес, вы можете непреднамеренно запретить некоторым пользователям просматривать содержимое в моделях с высотой, превышающей высоту видового экрана.
Еще один вариант: события колеса
Событие прокрутка не отменяется. Однако можно отменить колесико мыши и колесо события. Большой оговоркой является то, что не все их браузеры поддерживают их, Mozilla недавно добавила поддержку последней в Gecko 17.0. Я не знаю полного распространения, но IE6 + и Chrome поддерживают их.
Здесь, как использовать их:
$('#myModal')
.on('shown', function () {
$('body').on('wheel.modal mousewheel.modal', function () {
return false;
});
})
.on('hidden', function () {
$('body').off('wheel.modal mousewheel.modal');
});
Ответ 6
Вам нужно выйти за рамки ответа @charlietfl и учесть полосы прокрутки, в противном случае вы можете увидеть перекомпоновку документа.
Открытие модального:
- Запишите ширину
body
- Установить переполнение
body
hidden
-
Явно установите ширину тела, равную ширине шага 1.
var $body = $(document.body);
var oldWidth = $body.innerWidth();
$body.css("overflow", "hidden");
$body.width(oldWidth);
Закрытие модального:
- Установить переполнение
body
на auto
-
Установить ширину body
на auto
var $body = $(document.body);
$body.css("overflow", "auto");
$body.width("auto");
Вдохновлено: http://jdsharp.us/jQuery/minute/calculate-scrollbar-width.php
Ответ 7
Попробуйте следующее:
.modal-open {
overflow: hidden;
position:fixed;
width: 100%;
height: 100%;
}
это сработало для меня. (поддерживает IE8)
Ответ 8
/* =============================
* Disable / Enable Page Scroll
* when Bootstrap Modals are
* shown / hidden
* ============================= */
function preventDefault(e) {
e = e || window.event;
if (e.preventDefault)
e.preventDefault();
e.returnValue = false;
}
function theMouseWheel(e) {
preventDefault(e);
}
function disable_scroll() {
if (window.addEventListener) {
window.addEventListener('DOMMouseScroll', theMouseWheel, false);
}
window.onmousewheel = document.onmousewheel = theMouseWheel;
}
function enable_scroll() {
if (window.removeEventListener) {
window.removeEventListener('DOMMouseScroll', theMouseWheel, false);
}
window.onmousewheel = document.onmousewheel = null;
}
$(function () {
// disable page scrolling when modal is shown
$(".modal").on('show', function () { disable_scroll(); });
// enable page scrolling when modal is hidden
$(".modal").on('hide', function () { enable_scroll(); });
});
Ответ 9
Не удалось заставить его работать с Chrome, просто изменив CSS, потому что я не хотел, чтобы страница прокручивалась назад. Это отлично работает:
$("#myModal").on("show.bs.modal", function () {
var top = $("body").scrollTop(); $("body").css('position','fixed').css('overflow','hidden').css('top',-top).css('width','100%').css('height',top+5000);
}).on("hide.bs.modal", function () {
var top = $("body").position().top; $("body").css('position','relative').css('overflow','auto').css('top',0).scrollTop(-top);
});
Ответ 10
Я не уверен в этом коде, но это стоит того.
В jQuery:
$(document).ready(function() {
$(/* Put in your "onModalDisplay" here */)./* whatever */(function() {
$("#Modal").css("overflow", "hidden");
});
});
Как я уже говорил, я не уверен на 100%, но все равно стараюсь.
Ответ 11
Добавление класса 'is-modal-open' или изменение стиля тега body с помощью javascript в порядке, и оно будет работать так, как предполагается. Но проблема, с которой мы столкнемся, - это когда тело становится переполненным: скрытое, оно будет прыгать вверх, (scrollTop станет 0). Это станет проблемой юзабилити позже.
В качестве решения этой проблемы вместо изменения тега body over: скрытое изменение на html-теге
$('#myModal').on('shown.bs.modal', function () {
$('html').css('overflow','hidden');
}).on('hidden.bs.modal', function() {
$('html').css('overflow','auto');
});
Ответ 12
Для Bootstrap вы можете попробовать это (работает на Firefox
, Chrome
и Microsoft Edge
):
body.modal-open {
overflow: hidden;
position:fixed;
width: 100%;
}
Надеюсь это поможет...
Ответ 13
Вы можете использовать следующую логику, я ее протестировал и работает (даже в IE)
<html>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js"></script>
<script type="text/javascript">
var currentScroll=0;
function lockscroll(){
$(window).scrollTop(currentScroll);
}
$(function(){
$('#locker').click(function(){
currentScroll=$(window).scrollTop();
$(window).bind('scroll',lockscroll);
})
$('#unlocker').click(function(){
currentScroll=$(window).scrollTop();
$(window).unbind('scroll');
})
})
</script>
<div>
<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
<button id="locker">lock</button>
<button id="unlocker">unlock</button>
<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
</div>
Ответ 14
Лучшим решением является решение css-only body{overflow:hidden}
, используемое большинством этих ответов. Некоторые ответы содержат исправление, которое также предотвращает "прыжок", вызванный исчезновением полосы прокрутки; однако ни один из них не был слишком изящным. Итак, я написал эти две функции, и они, похоже, работают очень хорошо.
var $body = $(window.document.body);
function bodyFreezeScroll() {
var bodyWidth = $body.innerWidth();
$body.css('overflow', 'hidden');
$body.css('marginRight', ($body.css('marginRight') ? '+=' : '') + ($body.innerWidth() - bodyWidth))
}
function bodyUnfreezeScroll() {
var bodyWidth = $body.innerWidth();
$body.css('marginRight', '-=' + (bodyWidth - $body.innerWidth()))
$body.css('overflow', 'auto');
}
Просмотрите этот jsFiddle, чтобы увидеть его в использовании.
Ответ 15
На основе этой скрипты: http://jsfiddle.net/dh834zgw/1/
следующий фрагмент (с использованием jquery) отключит прокрутку окна:
var curScrollTop = $(window).scrollTop();
$('html').toggleClass('noscroll').css('top', '-' + curScrollTop + 'px');
И в вашем css:
html.noscroll{
position: fixed;
width: 100%;
top:0;
left: 0;
height: 100%;
overflow-y: scroll !important;
z-index: 10;
}
Теперь, когда вы удаляете модальный, не забудьте удалить класс noscroll в теге html:
$('html').toggleClass('noscroll');
Ответ 16
У меня была боковая панель, созданная с помощью checkbox hack.
Но основная идея - сохранить документ scrollTop и не изменять его во время прокрутки окна.
Мне просто не понравилась страница, прыгающая, когда тело становится "переполнением: скрыто".
window.addEventListener('load', function() {
let prevScrollTop = 0;
let isSidebarVisible = false;
document.getElementById('f-overlay-chkbx').addEventListener('change', (event) => {
prevScrollTop = window.pageYOffset || document.documentElement.scrollTop;
isSidebarVisible = event.target.checked;
window.addEventListener('scroll', (event) => {
if (isSidebarVisible) {
window.scrollTo(0, prevScrollTop);
}
});
})
});
Ответ 17
К сожалению, ни один из ответов выше не исправил мои проблемы.
В моей ситуации веб-страница изначально имеет полосу прокрутки. Всякий раз, когда я нажимаю модальный, полоса прокрутки не исчезает, а заголовок будет двигаться вправо немного.
Затем я попытался добавить .modal-open{overflow:auto;}
(что рекомендовано большинством людей). Это действительно исправило проблемы: полоса прокрутки появляется после того, как я открываю модальный. Однако возникает другой побочный эффект, который заключается в том, что "фон под заголовком будет перемещаться влево немного, вместе с другим длинным столбцом за модальным"
![Длинный бар за модальным]()
К счастью, после добавления {padding-right: 0 !important;}
все исправлено отлично. Оба фона заголовка и тела не перемещались, а модальная по-прежнему сохраняет полосу прокрутки.
![Фиксированное изображение]()
Надеюсь, это поможет тем, кто все еще придерживается этой проблемы. Удачи!
Ответ 18
Многие предлагают "переполнение: скрытое" на теле, которое не будет работать (не в моем случае, по крайней мере), так как это заставит веб-сайт прокручиваться вверх.
Это решение, которое работает для меня (как на мобильных телефонах, так и на компьютерах), используя jQuery:
$('.yourModalDiv').bind('mouseenter touchstart', function(e) {
var current = $(window).scrollTop();
$(window).scroll(function(event) {
$(window).scrollTop(current);
});
});
$('.yourModalDiv').bind('mouseleave touchend', function(e) {
$(window).off('scroll');
});
Это заставит прокрутку модаля работать и не позволит веб-сайту прокручиваться в одно и то же время.
Ответ 19
По состоянию на ноябрь 2017 года Chrome Введен новый объект css
overscroll-behavior: contain;
который решает эту проблему, хотя написание имеет ограниченную поддержку кросс-браузера.
см. ниже ссылки для получения полной информации и поддержки браузера
Ответ 20
Большинство частей здесь, но я не вижу ответа, который объединяет все это.
Проблема трехкратная.
(1) предотвратить прокрутку базовой страницы
$('body').css('overflow', 'hidden')
(2) и удалите полосу прокрутки
var handler = function (e) { e.preventDefault() }
$('.modal').bind('mousewheel touchmove', handler)
(3) очистить, когда модаль отклоняется
$('.modal').unbind('mousewheel touchmove', handler)
$('body').css('overflow', '')
Если модальный не полный экран, примените привязки .modal к полноэкранному наложению.
Ответ 21
Мое решение для Bootstrap 3:
.modal {
overflow-y: hidden;
}
body.modal-open {
margin-right: 0;
}
потому что для меня единственный overflow: hidden
в классе body.modal-open
не помешал переходу страницы влево из-за оригинала margin-right: 15px
.
Ответ 22
Я только что сделал это так...
$('body').css('overflow', 'hidden');
Но когда скроллер исчез, он переместил все 20px, поэтому я добавил
$('body').css('margin-right', '20px');
прямо после него.
Работает для меня.
Ответ 23
Я не уверен на 100%, что это будет работать с Bootstrap, но стоит попробовать - он работал с Remodal.js, который можно найти в github: http://vodkabears.github.io/remodal/, и было бы разумно, чтобы методы были довольно похожими.
Чтобы остановить перескакивание страницы вверху, а также предотвратить смещение содержимого справа, добавьте класс в body
, когда модаль запущен, и установите эти правила CSS:
body.with-modal {
position: static;
height: auto;
overflow-y: hidden;
}
Это position:static
и height:auto
, которые объединяются, чтобы остановить переключение содержимого вправо. overflow-y:hidden;
останавливает прокручивание страницы за модалом.
Ответ 24
Если модальные 100% высоты/ширины, "mouseenter/leave" будет работать, чтобы легко включать/отключать прокрутку. Это действительно сработало для меня:
var currentScroll=0;
function lockscroll(){
$(window).scrollTop(currentScroll);
}
$("#myModal").mouseenter(function(){
currentScroll=$(window).scrollTop();
$(window).bind('scroll',lockscroll);
}).mouseleave(function(){
currentScroll=$(window).scrollTop();
$(window).unbind('scroll',lockscroll);
});
Ответ 25
работал у меня
$('#myModal').on({'mousewheel': function(e)
{
if (e.target.id == 'el') return;
e.preventDefault();
e.stopPropagation();
}
});
Ответ 26
Это сработало для меня:
$("#mymodal").mouseenter(function(){
$("body").css("overflow", "hidden");
}).mouseleave(function(){
$("body").css("overflow", "visible");
});
Ответ 27
Для тех, кто задается вопросом, как получить событие прокрутки для модального bootstrap 3:
$(".modal").scroll(function() {
console.log("scrolling!);
});
Ответ 28
Это лучшее решение для меня:
Css:
.modal {
overflow-y: auto !important;
}
И Js:
modalShown = function () {
$('body').css('overflow', 'hidden');
},
modalHidden = function () {
$('body').css('overflow', 'auto');
}
Ответ 29
Я использую эту функцию vanilla js для добавления в тело класса "модально-открытый". (На основе smhmic ответа)
function freezeScroll(show, new_width)
{
var innerWidth = window.innerWidth,
clientWidth = document.documentElement.clientWidth,
new_margin = ((show) ? (new_width + innerWidth - clientWidth) : new_width) + "px";
document.body.style.marginRight = new_margin;
document.body.className = (show) ? "modal-open" : "";
};
Ответ 30
Скрытие переполнения и фиксация позиции делает трюк, однако, с моей жидкостной конструкцией, он фиксирует ее за шириной браузера, поэтому ширина: 100% исправлена.
body.modal-open{overflow:hidden;position:fixed;width:100%}