Как программно отключить прокрутку страницы с помощью jQuery
используя jQuery, я хотел бы отключить прокрутку тела:
моя идея:
- Set
body{ overflow: hidden;}
- захват текущего
scrollTop();/scrollLeft()
- привязка к событию прокрутки тела, установите scrollTop / scrollLeft в захваченное значение.
есть ли лучший способ?
обновление:
пожалуйста, см. мой пример, и причина, по http://jsbin.com/ikuma4/2/edit
Я знаю, кто-то будет думать "почему он просто не использовать position: fixed
на панели?".
пожалуйста, не предлагайте это, поскольку у меня есть другие причины.
22 ответов
единственный способ, которым я нашел это, похож на то, что вы описали:
- захватить текущее положение прокрутки (не забудьте горизонтальную ось!).
- установите overflow в hidden (вероятно, хотите сохранить Предыдущее значение переполнения).
- прокрутите документ до сохраненной позиции прокрутки с помощью scrollTo ().
затем, когда вы будете готовы разрешить прокрутку снова, отмените все это.
Edit: нет причин, по которым я не могу дать вам код, так как я пошел трудность выкопать его...
// lock scroll position, but retain settings for later
var scrollPosition = [
self.pageXOffset || document.documentElement.scrollLeft || document.body.scrollLeft,
self.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop
];
var html = jQuery('html'); // it would make more sense to apply this to body, but IE7 won't have that
html.data('scroll-position', scrollPosition);
html.data('previous-overflow', html.css('overflow'));
html.css('overflow', 'hidden');
window.scrollTo(scrollPosition[0], scrollPosition[1]);
// un-lock scroll position
var html = jQuery('html');
var scrollPosition = html.data('scroll-position');
html.css('overflow', html.data('previous-overflow'));
window.scrollTo(scrollPosition[0], scrollPosition[1])
Это полностью отключить прокрутку:
$('html, body').css({
overflow: 'hidden',
height: '100%'
});
восстановить:
$('html, body').css({
overflow: 'auto',
height: 'auto'
});
проверено на Firefox и Chrome.
попробуй такое
$('#element').on('scroll touchmove mousewheel', function(e){
e.preventDefault();
e.stopPropagation();
return false;
})
Я просто немного настраиваю решение на tfe. В частности, я добавил дополнительный контроль, чтобы убедиться, что есть нет смещения содержимого страницы (он же страница сдвига) когда полоса прокрутки установлено значение hidden
.
две функции Javascript lockScroll()
и unlockScroll()
можно определить, соответственно, для блокировки и разблокировки прокрутки страницы.
function lockScroll(){
$html = $('html');
$body = $('body');
var initWidth = $body.outerWidth();
var initHeight = $body.outerHeight();
var scrollPosition = [
self.pageXOffset || document.documentElement.scrollLeft || document.body.scrollLeft,
self.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop
];
$html.data('scroll-position', scrollPosition);
$html.data('previous-overflow', $html.css('overflow'));
$html.css('overflow', 'hidden');
window.scrollTo(scrollPosition[0], scrollPosition[1]);
var marginR = $body.outerWidth()-initWidth;
var marginB = $body.outerHeight()-initHeight;
$body.css({'margin-right': marginR,'margin-bottom': marginB});
}
function unlockScroll(){
$html = $('html');
$body = $('body');
$html.css('overflow', $html.data('previous-overflow'));
var scrollPosition = $html.data('scroll-position');
window.scrollTo(scrollPosition[0], scrollPosition[1]);
$body.css({'margin-right': 0, 'margin-bottom': 0});
}
где я предположил, что <body>
нет первоначального маржа.
обратите внимание, что, хотя вышеуказанное решение работает в большинстве практических случаев, оно не является окончательным, поскольку оно нуждается в дополнительной настройке для страниц, которые включают, например, заголовок с position:fixed
. Давайте рассмотрим этот особый случай на примере. Пусть
<body>
<div id="header">My fixedheader</div>
<!--- OTHER CONTENT -->
</body>
С
#header{position:fixed; padding:0; margin:0; width:100%}
затем следует добавить следующее в функции lockScroll()
и unlockScroll()
:
function lockScroll(){
//Omissis
$('#header').css('margin-right', marginR);
}
function unlockScroll(){
//Omissis
$('#header').css('margin-right', 0);
}
наконец, позаботьтесь о некоторых возможных начальное значение для полей или отступов.
чтобы отключить прокрутку, попробуйте следующее:
var current = $(window).scrollTop();
$(window).scroll(function() {
$(window).scrollTop(current);
});
для сброса:
$(window).off('scroll');
Я написал плагин jQuery для обработки этого:$.disablescroll.
это предотвращает прокрутку от событий mousewheel, touchmove и нажатия клавиш, таких как Страницы.
здесь демо здесь.
использование:
$(window).disablescroll();
// To re-enable scrolling:
$(window).disablescroll("undo");
вы можете прикрепить функцию к событиям прокрутки и предотвратить ее поведение по умолчанию.
var $window = $(window);
$window.on("mousewheel DOMMouseScroll", onMouseWheel);
function onMouseWheel(e) {
e.preventDefault();
}
один лайнер для отключения прокрутки, включая среднюю кнопку мыши.
$(document).scroll(function () { $(document).scrollTop(0); });
редактировать: в любом случае нет необходимости в jQuery, ниже того же, что и выше в vanilla JS(это означает отсутствие фреймворков, просто JavaScript):
document.addEventListener('scroll', function () { this.documentElement.scrollTop = 0; this.body.scrollTop = 0; })
этого.функцию documentelement.scrollTop - стандарт
этого.тело.scrollTop-IE совместимость
не можете ли вы просто установить высоту тела на 100% и скрыть переполнение? См.http://jsbin.com/ikuma4/13/edit
Это может или не может работать для ваших целей, но вы можете продлить jScrollPane для запуска других функций, прежде чем он сделает прокрутку. Я только что проверил это немного, но я могу подтвердить, что вы можете прыгнуть и полностью предотвратить прокрутку. Все, что я сделал, было:--5-->
- скачать демо zip:http://github.com/vitch/jScrollPane/archives/master
- откройте демонстрацию" события " (events.html)
- изменить его, чтобы использовать источник сценария без минификации:
<script type="text/javascript" src="script/jquery.jscrollpane.js"></script>
- внутри jquery.jscrollpane не.js, вставьте "return;" в строке 666 (благоприятный номер строки! но если ваша версия немного отличается, это первая строка
positionDragY(destY, animate)
функции
запуск событий.html, и вы увидите окно прокрутки, которое из-за вашего вмешательства в кодирование не будет прокручиваться.
таким образом вы можете управлять полосами прокрутки всего браузера (см. fullpage_scroll.формат HTML.)
Так, предположительно, следующий шаг-добавить вызов к какой-то другой функции, которая отключается и выполняет вашу магию привязки, а затем решает, продолжать ли прокрутку или нет. У вас также есть вызовы API для установки scrollTop и scrollLeft.
Если вы хотите больше помощи, сообщение, где вы получите до!
надеюсь, это помогло.
Я поставил ответ, который может помочь здесь: в jQuery simplemodal отключить прокрутку
Он показывает, как отключить полосы прокрутки без смещения текст вокруг. Вы можете игнорировать части о simplemodal.
кто-то опубликовал этот код, который имеет проблему не сохранения положения прокрутки при восстановлении. Причина в том, что люди склонны применять его к html и телу или только к телу, но он должен применяться только к html. Таким образом, при восстановлении положение прокрутки будет сохранено:
$('html').css({
'overflow': 'hidden',
'height': '100%'
});
восстановить:
$('html').css({
'overflow': 'auto',
'height': 'auto'
});
- Чтобы Скрыть Прокрутку:
$("body").css("overflow", "hidden");
- Для Восстановления Прокрутки:
$("body").css("overflow", "initial");
Если вы просто хотите отключить прокрутку с помощью навигации по клавиатуре, вы можете переопределить событие keydown.
$(document).on('keydown', function(e){
e.preventDefault();
e.stopPropagation();
});
попробуйте этот код:
$(function() {
// ...
var $body = $(document);
$body.bind('scroll', function() {
if ($body.scrollLeft() !== 0) {
$body.scrollLeft(0);
}
});
// ...
});
вы можете скрыть окно с помощью прокручиваемого div для предотвращения прокрутки содержимого на странице. И, скрывая и показывая, вы можете заблокировать/разблокировать свой свиток.
сделать что-то вроде этого:
#scrollLock {
width: 100%;
height: 100%;
position: fixed;
overflow: scroll;
opacity: 0;
display:none
}
#scrollLock > div {
height: 99999px;
}
function scrollLock(){
$('#scrollLock').scrollTop('10000').show();
}
function scrollUnlock(){
$('#scrollLock').hide();
}
для людей, у которых есть центрированные макеты (через margin:0 auto;
), вот пюре из position:fixed
С @tfeпредлагаемое решение.
используйте это решение, если вы испытываете привязку страницы (из-за полосы прокрутки, отображающей/скрывающей).
// lock scroll position, but retain settings for later
var scrollPosition = [
window.pageXOffset || document.documentElement.scrollLeft || document.body.scrollLeft,
window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop
];
var $html = $('html'); // bow to the demon known as MSIE(v7)
$html.addClass('modal-noscroll');
$html.data('scroll-position', scrollPosition);
$html.data('margin-top', $html.css('margin-top'));
$html.css('margin-top', -1 * scrollPosition[1]);
...в сочетании с...
// un-lock scroll position
var $html = $('html').removeClass('modal-noscroll');
var scrollPosition = $html.data('scroll-position');
var marginTop = $html.data('margin-top');
$html.css('margin-top', marginTop);
window.scrollTo(scrollPosition[0], scrollPosition[1])
...и, наконец, CSS для .modal-noscroll
...
.modal-noscroll
{
position: fixed;
overflow-y: scroll;
width: 100%;
}
Я бы рискнул сказать, что это более правильное решение, чем любое другое решение, но я не проверял его это тщательно еще...: P
Edit: обратите внимание, что я понятия не имею, насколько плохо это может работать (читать: взорвать) на сенсорном устройстве.
вы также можете использовать DOM для этого. Скажем, у вас есть функция, которую вы называете такой:
function disable_scroll() {
document.body.style.overflow="hidden";
}
и это все! Надеюсь, это поможет в дополнение ко всем другим ответам!
вот что я делал:
CoffeeScript:
$("input").focus ->
$("html, body").css "overflow-y","hidden"
$(document).on "scroll.stopped touchmove.stopped mousewheel.stopped", (event) ->
event.preventDefault()
$("input").blur ->
$("html, body").css "overflow-y","auto"
$(document).off "scroll.stopped touchmove.stopped mousewheel.stopped"
Javascript:
$("input").focus(function() {
$("html, body").css("overflow-y", "hidden");
$(document).on("scroll.stopped touchmove.stopped mousewheel.stopped", function(event) {
return event.preventDefault();
});
});
$("input").blur(function() {
$("html, body").css("overflow-y", "auto");
$(document).off("scroll.stopped touchmove.stopped mousewheel.stopped");
});
Не уверен, что кто-нибудь пробовал мое решение. Это работает на всем теле / html, но, без сомнения, его можно применить к любому элементу, который запускает событие прокрутки.
просто установите и снимите scrollLock, как вам нужно.
var scrollLock = false;
var scrollMem = {left: 0, top: 0};
$(window).scroll(function(){
if (scrollLock) {
window.scrollTo(scrollMem.left, scrollMem.top);
} else {
scrollMem = {
left: self.pageXOffset || document.documentElement.scrollLeft || document.body.scrollLeft,
top: self.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop
};
}
});
вот пример JSFiddle
надеюсь, что это поможет кому-то.
Я думаю, что лучшее и чистое решение:
window.addEventListener('scroll',() => {
var x = window.scrollX;
var y = window.scrollY;
window.scrollTo(x,y);
});
и с jQuery:
$(window).on('scroll',() => {
var x = window.scrollX;
var y = window.scrollY;
window.scrollTo(x,y)
})
эти прослушиватели событий должны блокировать прокрутку. Просто удалите их, чтобы повторно включить прокрутку