Просто отключить прокрутку, а не скрыть это? - PullRequest
172 голосов
/ 02 января 2012

Я пытаюсь отключить полосу прокрутки html / body родительского элемента, когда использую лайтбокс. Основное слово здесь отключить . Я не хочу скрыть это с overflow: hidden;.

Причина этого в том, что overflow: hidden заставляет сайт прыгать и занимать область, где находился свиток.

Я хочу знать, возможно ли отключить полосу прокрутки, пока она еще отображается.

Ответы [ 16 ]

149 голосов
/ 02 января 2012

Если страница под оверлеем может быть «зафиксирована» вверху, при открытии оверлея вы можете установить

body { position: fixed; overflow-y:scroll }

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

body { position: static; overflow-y:auto }

. Я просто предложил этот способ только потому, что вам не нужно изменять какое-либо событие прокрутки

Обновить

Вы также можете сделать небольшое улучшение: если вы получите свойство document.documentElement.scrollTop через javascript непосредственно перед открытием слоя, вы можете динамически назначить это значение как свойство top элемента body: при таком подходе страницабудет стоять на своем месте, независимо от того, находитесь ли вы на вершине или если вы уже прокрутили.

Css

.noscroll { position: fixed; overflow-y:scroll }

JS

$('body').css('top', -(document.documentElement.scrollTop) + 'px')
         .addClass('noscroll');
75 голосов
/ 15 декабря 2012

Четыре небольших дополнения к выбранному решению:

  1. Примените 'noscroll' к html вместо body , чтобы избежать двойных полос прокрутки в IE
  2. To проверьте, есть ли на самом деле полоса прокрутки перед добавлением класса 'noscroll'.В противном случае сайт также будет перепрыгивать при нажатии новой полосы прокрутки без прокрутки.
  3. Чтобы сохранить все возможные значения scrollTop , чтобы вся страница не возвращалась наверх (например, обновление Фабрицио)., но вам нужно получить значение перед добавлением класса 'noscroll')
  4. Не все браузеры обрабатывают scrollTop так же, как описано в http://help.dottoro.com/ljnvjiow.php

Полное решение, которое кажетсяработают для большинства браузеров:

CSS

html.noscroll {
    position: fixed; 
    overflow-y: scroll;
    width: 100%;
}

Отключить прокрутку

if ($(document).height() > $(window).height()) {
     var scrollTop = ($('html').scrollTop()) ? $('html').scrollTop() : $('body').scrollTop(); // Works for Chrome, Firefox, IE...
     $('html').addClass('noscroll').css('top',-scrollTop);         
}

Включить прокрутку

var scrollTop = parseInt($('html').css('top'));
$('html').removeClass('noscroll');
$('html,body').scrollTop(-scrollTop);

Спасибо Фабрицио и Деяну за то, что они поставили меня на правильный путь, и Бродинго за решение для двойной полосы прокрутки

32 голосов
/ 12 августа 2015

С включенным jQuery:


отключить

$.fn.disableScroll = function() {
    window.oldScrollPos = $(window).scrollTop();

    $(window).on('scroll.scrolldisabler',function ( event ) {
       $(window).scrollTop( window.oldScrollPos );
       event.preventDefault();
    });
};

включить

$.fn.enableScroll = function() {
    $(window).off('scroll.scrolldisabler');
};

использование

//disable
$("#selector").disableScroll();
//enable
$("#selector").enableScroll();
8 голосов
/ 17 августа 2017

Это сработало очень хорошо для меня ....

// disable scrolling
$('body').bind('mousewheel touchmove', lockScroll);

// enable scrolling
$('body').unbind('mousewheel touchmove', lockScroll);


// lock window scrolling
function lockScroll(e) {
    e.preventDefault();
}

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

например

$('button').on('click', function() {
     $('body').bind('mousewheel touchmove', lockScroll);
});
7 голосов
/ 20 июля 2016

Вы не можете отключить событие прокрутки, но вы можете отключить связанные действия, которые приводят к прокрутке, такие как колесико мыши и перемещение пальцем:

$('body').on('mousewheel touchmove', function(e) {
      e.preventDefault();
});
6 голосов
/ 23 июля 2016

Я ОП

С помощью ответа от fcalderan мне удалось сформировать решение.Я оставляю здесь свое решение, поскольку оно дает ясность в том, как его использовать, и добавляет очень важную деталь: width: 100%;

Я добавляю этот класс

body.noscroll
{
    position: fixed; 
    overflow-y: scroll;
    width: 100%;
}

, это сработало для меня, и яиспользовал Fancyapp.

3 голосов
/ 23 сентября 2016

Кроме того, вы можете скрыть полосу прокрутки тела с помощью overflow: hidden и в то же время установить поле, чтобы содержимое не перескочило:

let marginRightPx = 0;
if(window.getComputedStyle) {
    let bodyStyle = window.getComputedStyle(document.body);
    if(bodyStyle) {
        marginRightPx = parseInt(bodyStyle.marginRight, 10);
    }
}

let scrollbarWidthPx = window.innerWidth - document.body.clientWidth;
Object.assign(document.body.style, {
    overflow: 'hidden',
    marginRight: `${marginRightPx + scrollbarWidthPx}px`
});

А затем вы можете добавить отключенную полосу прокруткистраница для заполнения пробела:

textarea {
  overflow-y: scroll;
  overflow-x: hidden;
  width: 11px;
  outline: none;
  resize: none;
  position: fixed;
  top: 0;
  right: 0;
  bottom: 0;
  border: 0;
}
<textarea></textarea>

Я сделал именно это для собственной реализации лайтбокса.Кажется, до сих пор хорошо работает.

2 голосов
/ 27 сентября 2014

Это решение, с которым мы пошли.Просто сохраните позицию прокрутки при открытии оверлея, прокрутите назад до сохраненной позиции каждый раз, когда пользователь пытался прокрутить страницу, и отключите прослушиватель, когда оверлей закрыт., но работает как брелок в Firefox / Chrome.

var body = $("body"),
  overlay = $("#overlay"),
  overlayShown = false,
  overlayScrollListener = null,
  overlaySavedScrollTop = 0,
  overlaySavedScrollLeft = 0;

function showOverlay() {
  overlayShown = true;

  // Show overlay
  overlay.addClass("overlay-shown");

  // Save scroll position
  overlaySavedScrollTop = body.scrollTop();
  overlaySavedScrollLeft = body.scrollLeft();

  // Listen for scroll event
  overlayScrollListener = body.scroll(function() {
    // Scroll back to saved position
    body.scrollTop(overlaySavedScrollTop);
    body.scrollLeft(overlaySavedScrollLeft);
  });
}

function hideOverlay() {
  overlayShown = false;

  // Hide overlay
  overlay.removeClass("overlay-shown");

  // Turn scroll listener off
  if (overlayScrollListener) {
    overlayScrollListener.off();
    overlayScrollListener = null;
  }
}

// Click toggles overlay
$(window).click(function() {
  if (!overlayShown) {
    showOverlay();
  } else {
    hideOverlay();
  }
});
/* Required */
html, body { margin: 0; padding: 0; height: 100%; background: #fff; }
html { overflow: hidden; }
body { overflow-y: scroll; }

/* Just for looks */
.spacer { height: 300%; background: orange; background: linear-gradient(#ff0, #f0f); }
.overlay { position: fixed; top: 20px; bottom: 20px; left: 20px; right: 20px; z-index: -1; background: #fff; box-shadow: 0 0 5px rgba(0, 0, 0, .3); overflow: auto; }
.overlay .spacer { background: linear-gradient(#88f, #0ff); }
.overlay-shown { z-index: 1; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>

<h1>Top of page</h1>
<p>Click to toggle overlay. (This is only scrollable when overlay is <em>not</em> open.)</p>
<div class="spacer"></div>
<h1>Bottom of page</h1>
<div id="overlay" class="overlay">
  <h1>Top of overlay</h1>
  <p>Click to toggle overlay. (Containing page is no longer scrollable, but this is.)</p>
  <div class="spacer"></div>
  <h1>Bottom of overlay</h1>
</div>
1 голос
/ 30 сентября 2016

У меня была похожая проблема: левое меню, которое, когда оно появляется, предотвращает прокрутку.Как только высота была установлена ​​на 100vh, полоса прокрутки исчезла, и содержимое дернулось вправо.

Так что, если вы не против оставить полосу прокрутки включенной (но установите окно на полную высоту, чтобы оно не былона самом деле прокручивать в любом месте), тогда другая возможность - установить крошечное нижнее поле, при котором полосы прокрутки будут отображаться:

body {
    height: 100vh;
    overflow: hidden;
    margin: 0 0 1px;
}
0 голосов
/ 14 ноября 2018

Если страница под оверлеем может быть «исправлена» вверху, при открытии оверлея вы можете установить

.disableScroll { position: fixed; overflow-y:scroll }

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

Чтобы сохранить положение страницы, сделайте это в jquery

$('body').css('top', - ($(window).scrollTop()) + 'px').addClass('disableScroll');

Когда вы закроете оверлей, просто верните эти свойства с помощью

var top = $('body').position().top;
$('body').removeClass('disableScroll').css('top', 0).scrollTop(Math.abs(top));

Я просто предложил этот способ только потому, что вам не нужно менять какое-либо событие прокрутки

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...