Как запретить прокрутку страницы html
Перейти к содержимому

Как запретить прокрутку страницы html

  • автор:

Как убрать полосы прокрутки?

Убрать горизонтальные или вертикальные полосы прокрутки со страницы, не зависимо от объёма страницы.

Решение

Перед тем как убрать полосы прокрутки с веб-страницы, подумайте, действительно ли вам это так необходимо. Отсутствие возможности прокрутки содержимого документа создает трудности посетителям сайта для просмотра информации. Если же существует острая необходимость построения дизайнерских изысков или желание создать своим читателям трудности, то вперед. Но вас предупреждали!

Способ основан на использовании свойства overflow , которое добавляется к селектору HTML, как показано в примере 1.

Пример 1. Страница без полос прокрутки

HTML5 CSS2.1 IE Cr Op Sa Fx

    Полосы прокрутки html < overflow: hidden; >div 
Бла-бла

В данном примере используется значение hidden , которое «обрезает» весь контент выходящий за рамки элемента.

Также можно использовать свойство overflow-x , чтобы скрыть только горизонтальную полосу прокрутки и overflow-y — для сокрытия вертикальной полосы. В примере 2 показано добавление слоя с минимальной шириной 800 пикселов. При уменьшении окна браузера до этой величины, слой перестаёт менять свои размеры и появляется горизонтальная полоса прокрутки. С помощью свойства overflow-x полосы прокрутки скрываются.

Пример 2. Нет горизонтальной полосы прокрутки

HTML5 CSS3 IE Cr Op Sa Fx

    Полосы прокрутки   
Бла-бла

Свойства overflow-x и overflow-y входят в спецификацию CSS3 и не проходят валидацию при проверке стилей на CSS2.1.

Размеры и прокрутка страницы

Материал на этой странице устарел, поэтому скрыт из оглавления сайта.

Более новая информация по этой теме находится на странице https://learn.javascript.ru/size-and-scroll-window.

Как найти ширину окна браузера? Как узнать всю высоту страницы, с учётом прокрутки? Как прокрутить её из JavaScript?

С точки зрения HTML, документ – это document.documentElement . У этого элемента, соответствующего тегу , есть все стандартные свойства и метрики и, в теории, они и должны нам помочь. Однако, на практике есть ряд нюансов, именно их мы рассмотрим в этой главе.

Ширина/высота видимой части окна

Свойства clientWidth/Height для элемента document.documentElement – это как раз ширина/высота видимой области окна.

Например, кнопка ниже выведет размер такой области для этой страницы:

Не window.innerWidth/Height

Все браузеры, кроме IE8-, также поддерживают свойства window.innerWidth/innerHeight . Они хранят текущий размер окна браузера.

В чём отличие? Оно небольшое, но чрезвычайно важное.

Свойства clientWidth/Height , если есть полоса прокрутки, возвращают именно ширину/высоту внутри неё, доступную для документа, а window.innerWidth/Height – игнорируют её наличие.

Если справа часть страницы занимает полоса прокрутки, то эти строки выведут разное:

alert( window.innerWidth ); // вся ширина окна alert( document.documentElement.clientWidth ); // ширина минус прокрутка

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

Ширина/высота страницы с учётом прокрутки

Теоретически, видимая часть страницы – это documentElement.clientWidth/Height , а полный размер с учётом прокрутки – по аналогии, documentElement.scrollWidth/scrollHeight .

Это верно для обычных элементов.

А вот для страницы с этими свойствами возникает проблема, когда прокрутка то есть, то нет. В этом случае они работают некорректно. В браузерах Chrome/Safari и Opera при отсутствии прокрутки значение documentElement.scrollHeight в этом случае может быть даже меньше, чем documentElement.clientHeight , что, конечно же, выглядит как совершеннейшая чепуха и нонсенс.

Эта проблема возникает именно для documentElement , то есть для всей страницы.

Надёжно определить размер страницы с учётом прокрутки можно, взяв максимум из нескольких свойств:

var scrollHeight = Math.max( document.body.scrollHeight, document.documentElement.scrollHeight, document.body.offsetHeight, document.documentElement.offsetHeight, document.body.clientHeight, document.documentElement.clientHeight ); alert( 'Высота с учётом прокрутки: ' + scrollHeight );

Почему так? Лучше и не спрашивайте, это одно из редких мест, где просто ошибки в браузерах. Глубокой логики здесь нет.

Получение текущей прокрутки

У обычного элемента текущую прокрутку можно получить в scrollLeft/scrollTop .

Что же со страницей?

Большинство браузеров корректно обработает запрос к documentElement.scrollLeft/Top , однако Safari/Chrome/Opera есть ошибки (к примеру 157855, 106133), из-за которых следует использовать document.body .

Чтобы вообще обойти проблему, можно использовать специальные свойства window.pageXOffset/pageYOffset :

alert( 'Текущая прокрутка сверху: ' + window.pageYOffset ); alert( 'Текущая прокрутка слева: ' + window.pageXOffset );
  • Не поддерживаются IE8-
  • Их можно только читать, а менять нельзя.

Если IE8- не волнует, то просто используем эти свойства.

Кросс-браузерный вариант с учётом IE8 предусматривает откат на documentElement :

var scrollTop = window.pageYOffset || document.documentElement.scrollTop; alert( "Текущая прокрутка: " + scrollTop );

Изменение прокрутки: scrollTo, scrollBy, scrollIntoView

Чтобы прокрутить страницу при помощи JavaScript, её DOM должен быть полностью загружен.

На обычных элементах свойства scrollTop/scrollLeft можно изменять, и при этом элемент будет прокручиваться.

Никто не мешает точно так же поступать и со страницей. Во всех браузерах, кроме Chrome/Safari/Opera можно осуществить прокрутку установкой document.documentElement.scrollTop , а в указанных – использовать для этого document.body.scrollTop . И будет работать. Можно попробовать прокручивать и так и эдак и проверять, подействовала ли прокрутка, будет кросс-браузерно.

Но есть и другое, простое и универсальное решение – специальные методы прокрутки страницы window.scrollBy(x,y) и window.scrollTo(pageX,pageY).

  • Метод scrollBy(x,y) прокручивает страницу относительно текущих координат. Например, кнопка ниже прокрутит страницу на 10px вниз: window.scrollBy(0,10)
  • Метод scrollTo(pageX,pageY) прокручивает страницу к указанным координатам относительно документа. Он эквивалентен установке свойств scrollLeft/scrollTop . Чтобы прокрутить в начало документа, достаточно указать координаты (0,0) . window.scrollTo(0,0)

scrollIntoView

Для полноты картины рассмотрим также метод elem.scrollIntoView(top).

Метод elem.scrollIntoView(top) вызывается на элементе и прокручивает страницу так, чтобы элемент оказался вверху, если параметр top равен true , и внизу, если top равен false . Причём, если параметр top не указан, то он считается равным true .

Кнопка ниже прокрутит страницу так, чтобы кнопка оказалась вверху:

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

Запрет прокрутки

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

Чтобы запретить прокрутку страницы, достаточно поставить document.body.style.overflow = «hidden» .

При этом страница замрёт в текущем положении.

При нажатии на верхнюю кнопку страница замрёт на текущем положении прокрутки. После нажатия на нижнюю – прокрутка возобновится.

Вместо document.body может быть любой элемент, прокрутку которого необходимо запретить.

Недостатком этого способа является то, что сама полоса прокрутки исчезает. Если она занимала некоторую ширину, то теперь эта ширина освободится, и содержимое страницы расширится, текст «прыгнет», заняв освободившееся место.

Это может быть не очень красиво, но легко обходится, если вычислить размер прокрутки и добавить такой же по размеру padding .

Итого

  • Для получения размеров видимой части окна: document.documentElement.clientWidth/Height
  • Для получения размеров страницы с учётом прокрутки:

var scrollHeight = Math.max( document.body.scrollHeight, document.documentElement.scrollHeight, document.body.offsetHeight, document.documentElement.offsetHeight, document.body.clientHeight, document.documentElement.clientHeight );

Прокрутка окна:

    Прокрутку окна можно получить как window.pageYOffset (для горизонтальной – window.pageXOffset ) везде, кроме IE8-. На всякий случай – вот самый кросс-браузерный способ, учитывающий IE7- в том числе:

var html = document.documentElement; var body = document.body; var scrollTop = html.scrollTop || body && body.scrollTop || 0; scrollTop -= html.clientTop; // в IE7- смещён относительно (0,0) alert( "Текущая прокрутка: " + scrollTop );
  • window.scrollTo(pageX,pageY) – абсолютные координаты,
  • window.scrollBy(x,y) – прокрутить относительно текущего места.
  • elem.scrollIntoView(top) – прокрутить, чтобы элемент elem стал виден.

Задачи

Полифилл для pageYOffset в IE8

важность: 3

Обычно в IE8 не поддерживается свойство pageYOffset . Напишите полифилл для него.

При подключённом полифилле такой код должен работать в IE8:

// текущая прокрутка страницы в IE8 alert( window.pageYOffset );

В стандартном режиме IE8 можно получить текущую прокрутку так:

alert( document.documentElement.scrollTop );

Самым простым, но неверным было бы такое решение:

// "полифилл" window.pageYOffset = document.documentElement.scrollTop; // использование "полифилла" alert( window.pageYOffset );

Код выше не учитывает текущую прокрутку. Он присваивает window.pageYOffset текущую прокрутку, но при её изменении – не обновляет это свойство автоматически, а поэтому – бесполезен.

Более правильное решение – сделать это свойство геттером. При этом в IE8 для DOM-объектов работает Object.defineProperty :

// полифилл Object.defineProperty(window, 'pageYOffset', < get: function() < return document.documentElement.scrollTop; >>); // использование полифилла alert( window.pageYOffset );

Размеры и прокрутка окна

Как узнать ширину и высоту окна браузера? Как получить полную ширину и высоту документа, включая прокрученную часть? Как прокрутить страницу с помощью JavaScript?

Для большинства таких запросов мы можем использовать корневой элемент документа document.documentElement , который соответствует тегу . Однако есть дополнительные методы и особенности, которые необходимо учитывать.

Ширина/высота окна

Чтобы получить ширину/высоту окна, можно взять свойства clientWidth/clientHeight из document.documentElement :

Например, эта кнопка показывает высоту вашего окна:

Не window.innerWidth/Height

Браузеры также поддерживают свойства window.innerWidth/innerHeight . Вроде бы, похоже на то, что нам нужно. Почему же не использовать их?

Если есть полоса прокрутки, и она занимает какое-то место, то свойства clientWidth/clientHeight указывают на ширину/высоту документа без неё (за её вычетом). Иными словами, они возвращают высоту/ширину видимой части документа, доступной для содержимого.

А window.innerWidth/innerHeight включают в себя полосу прокрутки.

Если полоса прокрутки занимает некоторое место, то эти две строки выведут разные значения:

alert( window.innerWidth ); // полная ширина окна alert( document.documentElement.clientWidth ); // ширина окна за вычетом полосы прокрутки

В большинстве случаев нам нужна доступная ширина окна: для рисования или позиционирования. Полоса прокрутки «отъедает» её часть. Поэтому следует использовать documentElement.clientHeight/Width .

DOCTYPE – это важно

Обратите внимание, что геометрические свойства верхнего уровня могут работать немного иначе, если в HTML нет . Возможны странности.

В современном HTML мы всегда должны указывать DOCTYPE .

Ширина/высота документа

Теоретически, т.к. корневым элементом документа является documentElement , и он включает в себя всё содержимое, мы можем получить полный размер документа как documentElement.scrollWidth/scrollHeight .

Но именно на этом элементе, для страницы в целом, эти свойства работают не так, как предполагается. В Chrome/Safari/Opera, если нет прокрутки, то documentElement.scrollHeight может быть даже меньше, чем documentElement.clientHeight ! С точки зрения элемента это невозможная ситуация.

Чтобы надёжно получить полную высоту документа, нам следует взять максимальное из этих свойств:

let scrollHeight = Math.max( document.body.scrollHeight, document.documentElement.scrollHeight, document.body.offsetHeight, document.documentElement.offsetHeight, document.body.clientHeight, document.documentElement.clientHeight ); alert('Полная высота документа с прокручиваемой частью: ' + scrollHeight);

Почему? Лучше не спрашивайте. Эти несоответствия идут с древних времён. Глубокой логики здесь нет.

Получение текущей прокрутки

Обычные элементы хранят текущее состояние прокрутки в elem.scrollLeft/scrollTop .

Что же со страницей? В большинстве браузеров мы можем обратиться к documentElement.scrollLeft/Top , за исключением основанных на старом WebKit (Safari), где есть ошибка (5991), и там нужно использовать document.body вместо document.documentElement .

К счастью, нам совсем не обязательно запоминать эти особенности, потому что текущую прокрутку можно прочитать из свойств window.pageXOffset/pageYOffset :

alert('Текущая прокрутка сверху: ' + window.pageYOffset); alert('Текущая прокрутка слева: ' + window.pageXOffset);

Эти свойства доступны только для чтения.

В качестве свойств объекта window также доступны scrollX и scrollY

По историческим причинам существует два аналога window.pageXOffset и window.pageYOffset :

  • window.pageXOffset – то же самое, что и window.scrollX .
  • window.pageYOffset – то же самое, что и window.scrollY .

Прокрутка: scrollTo, scrollBy, scrollIntoView

Для прокрутки страницы из JavaScript её DOM должен быть полностью построен.

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

Обычные элементы можно прокручивать, изменяя scrollTop/scrollLeft .

Мы можем сделать то же самое для страницы в целом, используя document.documentElement.scrollTop/Left (кроме основанных на старом WebKit (Safari), где, как сказано выше, document.body.scrollTop/Left ).

Есть и другие способы, в которых подобных несовместимостей нет: специальные методы window.scrollBy(x,y) и window.scrollTo(pageX,pageY).

  • Метод scrollBy(x,y) прокручивает страницу относительно её текущего положения. Например, scrollBy(0,10) прокручивает страницу на 10px вниз. Кнопка ниже демонстрирует это: window.scrollBy(0,10)
  • Метод scrollTo(pageX,pageY) прокручивает страницу на абсолютные координаты (pageX,pageY) . То есть, чтобы левый-верхний угол видимой части страницы имел данные координаты относительно левого верхнего угла документа. Это всё равно, что поставить scrollLeft/scrollTop . Для прокрутки в самое начало мы можем использовать scrollTo(0,0) . window.scrollTo(0,0)

В обоих методах вместо координат также может использоваться объект options , как аргумент:

window.scrollTo(options); window.scrollBy(options);

options поддерживает три свойства:

window.scrollTo(< top: 100, left: 0, behavior: "smooth" >);
  • top – то же самое, что y / pageY
  • left – то же самое, что x / pageX
  • behavior – определяет, каким образом будет прокручиваться страница:
    • «smooth» – плавно (не поддерживается в IE и в старых версиях Safari)
    • «instant» – мгновенно
    • «auto» – определяется браузером (зависит от CSS-свойства scroll-behavior)

    Демонстрация плавной прокрутки страницы:

    scrollIntoView

    Для полноты картины давайте рассмотрим ещё один метод: elem.scrollIntoView(top).

    Вызов elem.scrollIntoView(top) прокручивает страницу, чтобы elem оказался вверху. У него есть один аргумент:

    • если top=true (по умолчанию), то страница будет прокручена, чтобы elem появился в верхней части окна. Верхний край элемента совмещён с верхней частью окна.
    • если top=false , то страница будет прокручена, чтобы elem появился внизу. Нижний край элемента будет совмещён с нижним краем окна.

    Кнопка ниже прокрутит страницу так, что она сама окажется вверху:

    А следующая кнопка прокрутит страницу так, что она сама окажется внизу

    Как и scrollTo / scrollBy , scrollIntoView также принимает объект options как аргумент (он немного отличается):

    this.scrollIntoView(options).

    options поддерживает три свойства:

    this.scrollIntoView(< behavior: "smooth", block: "end", inline: "nearest" >);
    • behavior – анимация прокрутки ( smooth , instant , auto )
    • block – вертикальное выравнивание ( start , center , end , nearest ). Значение по умолчанию: start
    • inline – горизонтальное выравнивание ( start , center , end , nearest ). Значение по умолчанию: nearest

    Запретить прокрутку

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

    Чтобы запретить прокрутку страницы, достаточно установить document.body.style.overflow = «hidden» .

    Первая кнопка останавливает прокрутку, вторая возобновляет её.

    Аналогичным образом мы можем «заморозить» прокрутку для других элементов, а не только для document.body .

    Недостатком этого способа является то, что сама полоса прокрутки исчезает. Если она занимала некоторую ширину, то теперь эта ширина освободится, и содержимое страницы расширится, текст «прыгнет», заняв освободившееся место.

    Это выглядит немного странно, но это можно обойти, если сравнить clientWidth до и после остановки, и если clientWidth увеличится (значит полоса прокрутки исчезла), то добавить padding в document.body вместо полосы прокрутки, чтобы оставить ширину содержимого прежней.

    Итого

    • Ширина/высота видимой части документа (ширина/высота области содержимого): document.documentElement.clientWidth/Height
    • Ширина/высота всего документа со всей прокручиваемой областью страницы:

    let scrollHeight = Math.max( document.body.scrollHeight, document.documentElement.scrollHeight, document.body.offsetHeight, document.documentElement.offsetHeight, document.body.clientHeight, document.documentElement.clientHeight );
    • Прокрутку окна можно получить так: window.pageYOffset/pageXOffset .
    • Изменить текущую прокрутку:
      • window.scrollTo(pageX,pageY) – абсолютные координаты,
      • window.scrollBy(x,y) – прокрутка относительно текущего места,
      • elem.scrollIntoView(top) – прокрутить страницу так, чтобы сделать elem видимым (выровнять относительно верхней/нижней части окна).

      Как запретить скролл не ставя overflow:hidden

      Как оставить полосу прокрутки и при этом запретить скролл на странице? Открывается модалка, и при этом, чтобы не было скролла всему html, который выше в несколько раз окна браузера, добавляется overflow:hidden, но при этом получается эффект прыгания по горизонтали из за того что полоса прокрутки то появляется, то исчезает. Как запретить скролл фона модалки не добавляя overflow:hidden, то есть оставив полосу прокрутки?

      html < position:relative; margin:0 auto; /*overflow:hidden; - не нужно использовать*/ height:100vh; width:100%; >html body:after < content:''; background-color:rgba(0, 0, 0, 0.5); position:fixed; top:0; left:0; right:0; bottom:0; z-index:9; >modal
      modal 
      1
      2
      3
      1
      2
      3
      1
      2
      3
      1
      2
      3
      1
      2
      3
      1
      2
      3
      1
      2
      3
      1
      2
      3
      1
      2
      3
      1
      2
      3
      1
      2
      3
      1
      2
      3
      1
      2
      3
      1
      2
      3
      1
      2
      3
      1
      2
      3
      1
      2
      3
      1
      2
      3
      1
      2
      3
      1
      2
      3
      1
      2
      3
      1
      2
      3
      1
      2
      3
      1
      2
      3
      1
      2
      3
      1
      2
      3
      1
      2
      3
      1
      2
      3
      1
      2
      3
      1
      2
      3
      1
      2
      3
      1
      2
      3
      1
      2
      3
      1
      2
      3
      1
      2
      3
      1
      2
      3
      1
      2
      3
      1
      2
      3
      1
      2
      3
      1
      2
      3
      1
      2
      3
      1
      2
      3
      1
      2
      3
      1
      2
      3
      1
      2
      3
      1
      2
      3
      1
      2
      3
      1
      2
      3
      1
      2
      3
      1
      2
      3
      1
      2
      3
      1
      2
      3
      1
      2
      3
      1
      2
      3
      1
      2
      3
      1
      2
      3
      1
      2
      3
      1
      2
      3
      1
      2
      3
      1
      2
      3
      1
      2
      3
      1
      2
      3
      1
      2
      3
      1
      2
      3
      1
      2
      3
      1
      2
      3
      1
      2
      3
      1
      2
      3
      1
      2
      3
      1
      2
      3
      1
      2
      3
      1
      2
      3
      1
      2
      3
      1
      2
      3
      1
      2
      3
      1
      2
      3
      1
      2
      3
      1
      2
      3
      1
      2
      3
      1
      2
      3
      1
      2
      3
      1
      2
      3
      1
      2
      3
      1
      2
      3
      1
      2
      3
      1
      2
      3
      1
      2
      3
      1
      2
      3
      1
      2
      3
      1
      2
      3
      1
      2
      3
      1
      2
      3
      1
      2
      3
      1
      2
      3
      1
      2
      3
      1
      2
      3
      1
      2
      3
      1
      2
      3
      1
      2
      3
      1
      2
      3
      1
      2
      3
      1
      2
      3
      1
      2
      3
      1
      2
      3
      1
      2
      3
      1
      2
      3
      1
      2
      3
      1
      2
      3
      1
      2
      3
      1
      2
      3
      1
      2
      3
      1
      2
      3
      1
      2
      3
      1
      2
      3
      1
      2
      3
      1
      2
      3
      1
      2
      3

      UPD: Должна остаться функция скролла внутри модалки. И нельзя потерять позицию в основном контенте при открытии модалки, поэтому position:fixed не подходит.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *