Как временно отключить прокрутку? - PullRequest
396 голосов
/ 22 января 2011

Я использую плагин scrollTo jQuery и хотел бы знать, возможно ли как-то временно отключить прокрутку элемента окна через Javascript?Причина, по которой я хотел бы отключить прокрутку, состоит в том, что когда вы прокручиваете, когда scrollTo анимирует, это становится действительно уродливым;)

Конечно, я мог бы сделать $("body").css("overflow", "hidden"); и затем вернуть его в автоматический режим, когдаанимация останавливается, но было бы лучше, если бы полоса прокрутки была видна, но не активна.

Ответы [ 33 ]

0 голосов
/ 03 октября 2015

У меня была похожая проблема с анимацией на мобильных экранах, но не на ноутбуках, при попытке анимировать div с помощью команды jquery animate.Поэтому я решил использовать таймер, который восстанавливал положение прокрутки окна так часто, что на первый взгляд документ казался статичным.Это решение отлично работало на мобильных устройствах с небольшим экраном, таких как Samsung Galaxy-2 или iphone-5.

Основная логика этого подхода : Таймер для установки положения прокрутки окна в исходное положение прокрутки должен быть запущен перед командой jquery animate, а затем, когда анимация завершена, нам нужно очистить этот таймер(original scroll position - это позиция непосредственно перед началом анимации).

Я обнаружил, к моему приятному удивлению , что документ действительно выглядит статичным в течение продолжительности анимации, если интервал таймера был 1 millisecond,к чему я стремился.

//get window scroll position prior to animation
//so we can keep this position during animation
var xPosition = window.scrollX || window.pageXOffset || document.body.scrollLeft;
var yPosition = window.scrollY || window.pageYOffset || document.body.scrollTop;

//NOTE:restoreTimer needs to be global variable
//start the restore timer
restoreTimer = setInterval(function() {
    window.scrollTo(xPosition, yPosition);
}, 1);

//animate the element emt
emt.animate({
    left: "toggle",
    top: "toggle",
    width: "toggle",
    height: "toggle"
}, 500, function() {
    //when animation completes, we stop the timer
    clearInterval(restoreTimer);
});

ДРУГОЕ РЕШЕНИЕ, которое сработало : Основываясь на ответе Мухаммеда Анини в этом посте на включение / отключение прокрутки, я также обнаружил, что работает модифицированная версия кода, как показано ниже.

//get current scroll position
var xPosition = window.scrollX || window.pageXOffset || document.body.scrollLeft;
var yPosition = window.scrollY || window.pageYOffset || document.body.scrollTop;

//disable scrolling
window.onscroll = function() {
    window.scrollTo(xPosition, yPosition);
};

//animate and enable scrolling when animation is completed
emt.animate({
    left: "toggle",
    top: "toggle",
    width: "toggle",
    height: "toggle"
}, 500, function() {
    //enable scrolling when animation is done
    window.onscroll = function() {};
});
0 голосов
/ 26 апреля 2013

Я нашел этот ответ на другом сайте :

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

$( ".popup").live({
    popupbeforeposition: function(event, ui) {
    $("body").on("touchmove", false);
}
});

После закрытия прокрутки всплывающего окна:

$( ".popup" ).live({
    popupafterclose: function(event, ui) {
    $("body").unbind("touchmove");
}
});
0 голосов
/ 20 февраля 2017

Что-то, что я только что собрал:

jsfiddle

document.onwheel = function(e) {
  // get the target element
  target = e.target;
  // the target element might be the children of the scrollable element
  // e.g., "li"s inside an "ul", "p"s inside a "div" etc.
  // we need to get the parent element and check if it is scrollable
  // if the parent isn't scrollable, we move up to the next parent
  while (target.scrollHeight <= target.clientHeight) {
    // while looping parents, we'll eventually reach document.body
    // since body doesn't have a parent, we need to exit the while loop
    if (target == document.body) {
      break;
    }
    target = target.parentElement;
  }
  // we want this behaviour on elements other than the body
  if (target != document.body) {
    // if the scrollbar is at the top and yet if it still tries to scroll up
    // we prevent the scrolling
    if (target.scrollTop <= 0 && e.deltaY < 0) {
      e.preventDefault();
    }
    // similarly, if the scrollbar is at the bottom and it still tries to scroll down
    // we prevent it
    else if (target.clientHeight + target.scrollTop >= target.scrollHeight && e.deltaY > 0) {
      e.preventDefault();
    }
  }
};
body {
  background: gainsboro;
}

#box {
  width: 300px;
  height: 600px;
  padding: 5px;
  border: 1px solid silver;
  margin: 50px auto;
  background: white;
  overflow: auto;
}
<div id="box">
  <p>
    Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor
    in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
  </p>
  <p>
    Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor
    in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
  </p>
  <p>
    Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor
    in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
  </p>
  <p>
    Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor
    in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
  </p>
</div>
0 голосов
/ 05 июля 2014

Вы можете заблокировать прокрутку пробела и скрыть полосу прокрутки браузера:

$(document).keydown(function(event) {
    if (event.keyCode == 32) {
        return false;

    }
});

document.documentElement.style.overflow = 'hidden';
document.body.scroll = 'no';
0 голосов
/ 13 сентября 2018

Это самое простое решение, которое я получил до сих пор. И поверьте мне, я попробовал все остальные, и это самый простой. Он отлично работает на устройствах с Windows , при котором страница перемещается справа, чтобы освободить место для системной полосы прокрутки, и устройств IOS , которым не требуется место для их полос прокрутки в браузерах. Таким образом, при использовании этого вам не нужно добавлять отступ справа, чтобы страница не мерцала, когда вы скрываете переполнение тела или HTML с помощью css .

Решение довольно простое, если подумать. Идея состоит в том, чтобы дать window.scrollTop () такую ​​же точную позицию в момент открытия всплывающего окна. Также измените эту позицию, когда размер окна изменится (так как позиция прокрутки изменяется, когда это происходит).

Итак, поехали ...

Сначала давайте создадим переменную, которая сообщит вам, что всплывающее окно открыто, и назовем ее stopWindowScroll . Если мы этого не сделаем, вы получите ошибку неопределенной переменной на своей странице и установите ее на 0 - как неактивную.

$(document).ready(function(){
    stopWindowScroll = 0;
});

Теперь давайте сделаем так, чтобы функция open popup могла быть любой функцией в вашем коде, которая запускает любое всплывающее окно, которое вы используете в качестве плагина или пользовательского. В этом случае это будет простое настраиваемое всплывающее окно с простой функцией документа при нажатии.

$(document).on('click','.open-popup', function(){
    // Saving the scroll position once opening the popup.
    stopWindowScrollPosition = $(window).scrollTop();
    // Setting the stopWindowScroll to 1 to know the popup is open.
    stopWindowScroll = 1;
    // Displaying your popup.
    $('.your-popup').fadeIn(300);
});

Итак, следующее, что мы делаем, это создаем всплывающую функцию close, которая, повторяю еще раз, может быть любой функцией, которую вы уже создали или используете в плагине. Важно то, что эти две функции нужны для установки переменной stopWindowScroll на 1 или 0, чтобы знать, когда она открыта или закрыта.

$(document).on('click','.open-popup', function(){
    // Setting the stopWindowScroll to 0 to know the popup is closed.
    stopWindowScroll = 0;
    // Hiding your popup
    $('.your-popup').fadeOut(300);
});

Затем давайте создадим функцию window.scroll, чтобы мы могли предотвратить прокрутку, как только упомянутый выше stopWindowScroll установлен в 1 - как активный.

$(window).scroll(function(){
    if(stopWindowScroll == 1) {
         // Giving the window scrollTop() function the position on which
         // the popup was opened, this way it will stay in its place.
         $(window).scrollTop(stopWindowScrollPosition);
    }
});

Вот и все. Для этого не требуется CSS, кроме ваших собственных стилей для страницы. Для меня это сработало, и я надеюсь, что это поможет вам и другим.

Вот рабочий пример на JSFiddle:

Пример JS Fiddle

Дайте мне знать, если это помогло. Привет.

0 голосов
/ 01 марта 2016

Простое решение, которое сработало для меня (временно отключив прокрутку окна).

На основе этой скрипки: 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');
0 голосов
/ 07 июля 2012

Я нашел лучший, но ошибочный способ, сочетающий идею sdleihssirhc:

window.onscroll = function() {
    window.scrollTo(window.scrollX, window.scrollY);
    //Or
    //window.scroll(window.scrollX, window.scrollY);
    //Or Fallback
    //window.scrollX=window.scrollX;
    //window.scrollY=window.scrollY;
};

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

0 голосов
/ 28 мая 2018

У меня похожая проблема на сенсорных устройствах.Добавление «touch-action: none» к элементу решило проблему.

Для получения дополнительной информации.Проверьте это: -

https://developer.mozilla.org/en-US/docs/Web/CSS/touch-action

0 голосов
/ 20 февраля 2016

Мое рассмотрение этого вопроса также включает в себя проблему ширины тела, поскольку страница, кажется, немного плясает, когда мы скрываем полосу прокрутки с помощью overflow = "hidden". Следующий код отлично работает для меня и основан на угловом подходе.

element.bind('mouseenter', function() {
    var w = document.body.offsetWidth;
    document.body.style.overflow = 'hidden';
    document.body.style.width = w + 'px';
});

element.bind('mouseleave', function() {
    document.body.style.overflow = 'initial';
    document.body.style.width = 'auto';
});
0 голосов
/ 31 октября 2018

Сохраните длину прокрутки в глобальной переменной и восстановите ее при необходимости!

var sctollTop_length = 0;

function scroll_pause(){
  sctollTop_length = $(window).scrollTop();
  $("body").css("overflow", "hidden");
}

function scroll_resume(){
  $("body").css("overflow", "auto");
  $(window).scrollTop(sctollTop_length);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...