Как программно отключить прокрутку страницы с помощью jQuery

используя jQuery, я хотел бы отключить прокрутку тела:

моя идея:

  1. Set body{ overflow: hidden;}
  2. захват текущего scrollTop();/scrollLeft()
  3. привязка к событию прокрутки тела, установите scrollTop / scrollLeft в захваченное значение.

есть ли лучший способ?


обновление:

пожалуйста, см. мой пример, и причина, по http://jsbin.com/ikuma4/2/edit

Я знаю, кто-то будет думать "почему он просто не использовать position: fixed на панели?".

пожалуйста, не предлагайте это, поскольку у меня есть другие причины.

22 ответов


единственный способ, которым я нашел это, похож на то, что вы описали:

  1. захватить текущее положение прокрутки (не забудьте горизонтальную ось!).
  2. установите overflow в hidden (вероятно, хотите сохранить Предыдущее значение переполнения).
  3. прокрутите документ до сохраненной позиции прокрутки с помощью 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;
})

вы можете использовать этот код:

$("body").css("overflow", "hidden");

Я просто немного настраиваю решение на 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();
}

https://jsfiddle.net/22cLw9em/


один лайнер для отключения прокрутки, включая среднюю кнопку мыши.

$(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)
})

эти прослушиватели событий должны блокировать прокрутку. Просто удалите их, чтобы повторно включить прокрутку