Как добавить элементу полосу прокрутки по вертикали
Перейти к содержимому

Как добавить элементу полосу прокрутки по вертикали

  • автор:

Изменение вертикальной прокрутки на горизонтальную в точке для определенного элемента

Каков контекст проблемы? У меня есть веб-сайт, представляющий собой одну страницу, на которой я буду представлять свою деятельность и проекты. После прокрутки нескольких разделов у нас есть проекты подряд. Что я хочу сделать ? Я хочу поменять вертикальную прокрутку на горизонтальную, когда мы дойдем до горизонтальной строки моих проектов. Когда вы находитесь в конце ряда, он просто должен вернуться в нормальное состояние с помощью вертикальной прокрутки. Код

Вот мой код. И что я делал У меня есть метод inTheMiddle() , который является логическим. Если находится в середине области просмотра, он возвращает true , иначе false . Метод scrollDirection() , который также является логическим, true , когда прокрутка идет вниз, false , когда она идет вверх. Есть Множество различных методов disableScroll() Последний метод disableScroll() отменяет прокрутку, пересчитывая ее.

componentDidMount() < window.addEventListener('wheel', (this.handleScroll)); >. disableScroll() < // Get the current page scroll position const scrollTop = window.pageYOffset || document.documentElement.scrollTop; const scrollLeft = window.pageXOffset || document.documentElement.scrollLeft; // if any scroll is attempted, set this to the previous value window.onscroll = () =>< window.scrollTo(scrollLeft, scrollTop); >; > 

И ещё мой метод handleScroll() , который управляет всем этим

handleScroll(event) < const rowProjects = document.querySelector(".row.projects") const projectsContainer = document.querySelector(".projectsContainer") const isSticky = rowProjects.classList.contains("sticky") // isSticky is useless now was try by adding position fixed and no need to use disableScroll() if (this.inTheMiddle() && this.state.scrollDown && this.state.count < 1400 ) < this.disableScroll() this.setState(< count: this.state.count + 10 >) rowProjects.scroll(this.state.count, 0) > else if ((!this.state.scrollDown) && this.state.count > 0) < this.setState(< count: this.state.count - 10 >) rowProjects.scroll(this.state.count, 0) > > 

Чего я не могу сделать, так это вернуться к нормальному состоянию прокрутки. Когда вы достигаете конца строки, я не могу повторно включить прокрутку, когда я прокручиваю страницу вверх. Он застрял в строке проектов. Я справился с этим с помощью isSticky . Я удалил disableScroll() и добавил класс с фиксированной позицией, но проблема заключалась в том, что он отскочил. Потому что, когда он находится посередине, я зафиксировался в середине области просмотра, поэтому элемент больше не находится в относительном положении, поэтому он подпрыгнул, как сбой (например, сняв блокировку блока стека), извините за плохой пример :’) Если у вас есть идея помочь мне, это было бы очень любезно. Ломаю голову уже 3 дня и так и не нашел идеального решения. Свободный перевод вопроса Changing vertical scroll to horizontal at a point for a specific element от участника @crg.

Отслеживать
задан 24 июн 2022 в 16:44
Alexandr_TT Alexandr_TT
110k 23 23 золотых знака 114 114 серебряных знаков 386 386 бронзовых знаков
ассоциация:stackoverflow.com/q/63996962/7394871
24 июн 2022 в 16:47
Такие ухищрения, чтобы сделать безобразный эффект, за который дизайнерам сайтов надо отбивать руки.
24 июн 2022 в 16:49

@Инквизитор ничего безобразного не вижу. Вариант имеет право на жизнь. Сначала вертикальная прокрутка, потом горизонтальная прокрутка и снова вертикальная. Впрочем у каждого свои вкусы, фломастеры.

24 июн 2022 в 16:55

1 ответ 1

Сортировка: Сброс на вариант по умолчанию

Это должно работать нормально. Вы можете выполнить вертикальную прокрутку и использовать значение window.scrollY для смещения элемента по горизонтали, назначив его значение в element.style.left , тем самым придав ему эффект горизонтальной прокрутки. Я сделал то же самое, и это сработало.

(См. результат в полноэкранном режиме).

var content = document.getElementById('content_2'); window.addEventListener('scroll', function() < var scrolledY = window.scrollY; var scrolledX = window.scrollX; if (scrolledY >625 && scrolledY < 3112) < content.style.marginTop = 150 + 'px'; content.style.position = "fixed"; content.style.top = scrolledY * 0.001 + 'px'; content.style.left = -(scrolledY - 625) * 0.55 + 'px'; >if (scrolledY if (scrolledY >= 3112) < content.style.position = "absolute"; content.style.top = 3112 + 'px'; >>);
* < margin: 0px; padding: 0px; font-family: 'Arial'; overflow-x: hidden; scroll-behavior: smooth; >body < min-height: 4400px; >.content_1, .content_2 < height: 100vh; width: 100vw; >.content_1 < background-color: black; color: white; >.content_1 h1 < font-size: 200px; text-align: center; >.content_2 < margin-top: 150px; top: 625px; white-space: nowrap; display: flex; height: 80vh; width: 200vw; position: fixed; flex-direction: row; flex-wrap: nowrap; >.content_3 < font-size: 20px; margin-top: 3050px; >.card
 

First Page

Card-1
Card-2
Card-3
Card-4
Card-5
Card-6
Card-7
Card-8

Senectus purus, molestie blandit sociis eu leo blandit platea commodo aptent scelerisque cursus. Hac vel himenaeos hendrerit eu pellentesque. Lorem natoque praesent dictum porta, aliquam bibendum laoreet class litora? Class nullam maecenas aliquet. Ligula, et enim vel rutrum luctus lorem orci fringilla in erat? Bibendum magnis nec volutpat non netus dignissim. Tempus tempor penatibus nulla egestas semper scelerisque cubilia. Nulla adipiscing per porta consequat et imperdiet posuere magna fringilla rhoncus conubia. Sapien proin euismod.

Tempus luctus tempor donec pretium lectus leo facilisis leo, inceptos nostra lorem vel. Orci parturient urna etiam pharetra sit lacus volutpat id sed lacinia. Scelerisque ultrices nisi risus aenean tincidunt, amet arcu tempus id curabitur purus fringilla. Eros iaculis vitae vitae rutrum ultricies dolor sociis ante ante ut. Ut nibh primis himenaeos egestas dictumst congue scelerisque!

Blandit sociis quisque ultrices montes tortor. Penatibus risus primis, senectus nam nostra. Egestas, nulla vitae penatibus cursus sed. Luctus, eget dignissim porttitor et curae; accumsan. Accumsan blandit ligula sollicitudin. Ligula mattis ad turpis arcu mus laoreet conubia risus accumsan quis lobortis. Nisi sollicitudin penatibus lacus nam justo id commodo sagittis. Leo orci.

Fringilla sociosqu laoreet id, dui lobortis condimentum? Facilisis non, cubilia diam. Egestas aptent ornare et felis morbi senectus molestie, egestas donec himenaeos ultrices himenaeos. Condimentum conubia nisl urna lobortis pharetra adipiscing cras eget pellentesque sollicitudin faucibus. Scelerisque lobortis nascetur neque ac quam dignissim fames. Magnis pharetra dignissim nullam sapien eu curabitur, ridiculus dapibus. Aptent tempus nibh eget scelerisque magna ipsum turpis. Taciti nostra morbi pharetra montes sagittis posuere mollis.

Taciti tortor phasellus placerat inceptos tristique consectetur accumsan vitae potenti sodales nulla eros. Dapibus scelerisque penatibus nisl accumsan ultricies ridiculus porta. Varius tellus erat laoreet morbi tempor tristique. Sapien, sem morbi libero dapibus curabitur. Facilisi habitasse feugiat semper magnis risus id tellus libero semper. Vehicula turpis elit lectus interdum metus ultrices mollis consectetur cubilia.

Senectus purus, molestie blandit sociis eu leo blandit platea commodo aptent scelerisque cursus. Hac vel himenaeos hendrerit eu pellentesque. Lorem natoque praesent dictum porta, aliquam bibendum laoreet class litora? Class nullam maecenas aliquet. Ligula, et enim vel rutrum luctus lorem orci fringilla in erat? Bibendum magnis nec volutpat non netus dignissim. Tempus tempor penatibus nulla egestas semper scelerisque cubilia. Nulla adipiscing per porta consequat et imperdiet posuere magna fringilla rhoncus conubia. Sapien proin euismod.

Tempus luctus tempor donec pretium lectus leo facilisis leo, inceptos nostra lorem vel. Orci parturient urna etiam pharetra sit lacus volutpat id sed lacinia. Scelerisque ultrices nisi risus aenean tincidunt, amet arcu tempus id curabitur purus fringilla. Eros iaculis vitae vitae rutrum ultricies dolor sociis ante ante ut. Ut nibh primis himenaeos egestas dictumst congue scelerisque!

Blandit sociis quisque ultrices montes tortor. Penatibus risus primis, senectus nam nostra. Egestas, nulla vitae penatibus cursus sed. Luctus, eget dignissim porttitor et curae; accumsan. Accumsan blandit ligula sollicitudin. Ligula mattis ad turpis arcu mus laoreet conubia risus accumsan quis lobortis. Nisi sollicitudin penatibus lacus nam justo id commodo sagittis. Leo orci.

Fringilla sociosqu laoreet id, dui lobortis condimentum? Facilisis non, cubilia diam. Egestas aptent ornare et felis morbi senectus molestie, egestas donec himenaeos ultrices himenaeos. Condimentum conubia nisl urna lobortis pharetra adipiscing cras eget pellentesque sollicitudin faucibus. Scelerisque lobortis nascetur neque ac quam dignissim fames. Magnis pharetra dignissim nullam sapien eu curabitur, ridiculus dapibus. Aptent tempus nibh eget scelerisque magna ipsum turpis. Taciti nostra morbi pharetra montes sagittis posuere mollis.

Taciti tortor phasellus placerat inceptos tristique consectetur accumsan vitae potenti sodales nulla eros. Dapibus scelerisque penatibus nisl accumsan ultricies ridiculus porta. Varius tellus erat laoreet morbi tempor tristique. Sapien, sem morbi libero dapibus curabitur. Facilisi habitasse feugiat semper magnis risus id tellus libero semper. Vehicula turpis elit lectus interdum metus ultrices mollis consectetur cubilia.

Свободный перевод ответа от участника @Ac_mmi.

Как сделать скролл внутри блока css

Для создания блока фиксированного размера с возможностью прокрутки по горизонтали и вертикали необходимо использовать свойство overflow .

Overflow может принимать следующие значения:

  • visible: По умолчанию. Содержимое не обрезается, может отображаться снаружи блока, в котором оно расположено.
  • hidden: Контент обрезается, без предоставления прокрутки.
  • scroll: Содержимое обрезается и браузер использует элементы прокрутки, не важно было ли обрезано содержимое или нет. Это избегает многих проблем касательно появления прокруток и их исчезновения в динамичной среде. Принтеры могут печатать переполненное содержимое.
  • auto: Зависит от агента пользователя. Браузеры такие как Firefox предоставляют прокрутку, если содержимое переполняет блок.

Исходный HTML документ:

 Пример текста, который будет в блоке с полосами прокрути - как горизонтальной так и вертикальной. Для того что бы ими можно было воспользоваться, добавим д____л____и____н____н____о_____е слово. 
div  border: 1px solid #000; width: 200px; height: 50px; /* Включаем отображение полос прокрутки по горизонтали и по вертикали */ overflow: auto; padding: 20px; > 

auto-scroll

Результат:

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

Существует множество JavaScript-свойств, которые позволяют считывать информацию об элементе: ширину, высоту и другие геометрические характеристики. В этой главе мы будем называть их «метрики».

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

Простой пример

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

 
#example

У элемента есть рамка (border), внутренний отступ (padding) и прокрутка. Полный набор характеристик. Обратите внимание, тут нет внешних отступов (margin), потому что они не являются частью элемента, для них нет особых JavaScript-свойств.

Результат выглядит так:

Внимание, полоса прокрутки

В иллюстрации выше намеренно продемонстрирован самый сложный и полный случай, когда у элемента есть ещё и полоса прокрутки. Некоторые браузеры (не все) отбирают место для неё, забирая его у области, отведённой для содержимого (помечена как «content width» выше).

Таким образом, без учёта полосы прокрутки ширина области содержимого (content width) будет 300px , но если предположить, что ширина полосы прокрутки равна 16px (её точное значение зависит от устройства и браузера), тогда остаётся только 300 — 16 = 284px , и мы должны это учитывать. Вот почему примеры в этой главе даны с полосой прокрутки. Без неё некоторые вычисления будут проще.

Область padding-bottom (нижний внутренний отступ) может быть заполнена текстом

Нижние внутренние отступы padding-bottom изображены пустыми на наших иллюстрациях, но если элемент содержит много текста, то он будет перекрывать padding-bottom , это нормально.

Метрики

Вот общая картина с геометрическими свойствами:

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

Давайте начнём исследовать, начиная снаружи элемента.

offsetParent, offsetLeft/Top

Эти свойства редко используются, но так как они являются «самыми внешними» метриками, мы начнём с них.

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

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

Свойства offsetLeft/offsetTop содержат координаты x/y относительно верхнего левого угла offsetParent .

В примере ниже внутренний имеет элемент в качестве offsetParent , а свойства offsetLeft/offsetTop являются сдвигами относительно верхнего левого угла ( 180 ):

 
.

Существует несколько ситуаций, когда offsetParent равно null :

  1. Для скрытых элементов (с CSS-свойством display:none или когда его нет в документе).
  2. Для элементов и .
  3. Для элементов с position:fixed .

offsetWidth/Height

Теперь переходим к самому элементу.

Эти два свойства – самые простые. Они содержат «внешнюю» ширину/высоту элемента, то есть его полный размер, включая рамки.

Для нашего элемента:

Метрики для не показываемых элементов равны нулю.

Координаты и размеры в JavaScript устанавливаются только для видимых элементов.

Если элемент (или любой его родитель) имеет display:none или отсутствует в документе, то все его метрики равны нулю (или null , если это offsetParent ).

Например, свойство offsetParent равно null , а offsetWidth и offsetHeight равны 0 , когда мы создали элемент, но ещё не вставили его в документ, или если у элемента (или у его родителя) display:none .

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

function isHidden(elem)

Заметим, что функция isHidden также вернёт true для элементов, которые в принципе показываются, но их размеры равны нулю.

clientTop/Left

Пойдём дальше. Внутри элемента у нас рамки (border).

Для них есть свойства-метрики clientTop и clientLeft .

В нашем примере:

…Но на самом деле эти свойства – вовсе не ширины рамок, а отступы внутренней части элемента от внешней.

В чём же разница?

Она возникает, когда документ располагается справа налево (операционная система на арабском языке или иврите). Полоса прокрутки в этом случае находится слева, и тогда свойство clientLeft включает в себя ещё и ширину полосы прокрутки.

В этом случае clientLeft будет равно 25 , но с прокруткой – 25 + 16 = 41 .

Вот соответствующий пример на иврите:

clientWidth/Height

Эти свойства – размер области внутри рамок элемента.

Они включают в себя ширину области содержимого вместе с внутренними отступами padding , но без прокрутки:

На рисунке выше посмотрим вначале на высоту clientHeight .

Горизонтальной прокрутки нет, так что это в точности то, что внутри рамок: CSS-высота 200px плюс верхние и нижние внутренние отступы ( 2 * 20px ), итого 240px .

Теперь clientWidth – ширина содержимого здесь равна не 300px , а 284px , т.к. 16px отведено для полосы прокрутки. Таким образом: 284px плюс левый и правый отступы – всего 324px .

Если нет внутренних отступов padding , то clientWidth/Height в точности равны размеру области содержимого внутри рамок за вычетом полосы прокрутки (если она есть).

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

scrollWidth/Height

Эти свойства – как clientWidth/clientHeight , но также включают в себя прокрученную (которую не видно) часть элемента.

На рисунке выше:

Эти свойства можно использовать, чтобы «распахнуть» элемент на всю ширину/высоту.

// распахнуть элемент на всю высоту element.style.height = `$px`;

Нажмите на кнопку, чтобы распахнуть элемент:

текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст

scrollLeft/scrollTop

Свойства scrollLeft/scrollTop – ширина/высота невидимой, прокрученной в данный момент, части элемента слева и сверху.

Следующая иллюстрация показывает значения scrollHeight и scrollTop для блока с вертикальной прокруткой.

Другими словами, свойство scrollTop – это «сколько уже прокручено вверх».

Свойства scrollLeft/scrollTop можно изменять

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

При клике на следующий элемент будет выполняться код elem.scrollTop += 10 . Поэтому он будет прокручиваться на 10px вниз.

Кликни
Меня
1
2
3
4
5
6
7
8
9

Установка значения scrollTop на 0 или на большое значение, такое как 1e9 , прокрутит элемент в самый верх/низ соответственно.

Не стоит брать width/height из CSS

Мы рассмотрели метрики, которые есть у DOM-элементов, и которые можно использовать для получения различных высот, ширин и прочих расстояний.

Но как мы знаем из главы Стили и классы, CSS-высоту и ширину можно извлечь, используя getComputedStyle .

Так почему бы не получать, к примеру, ширину элемента при помощи getComputedStyle , вот так?

let elem = document.body; alert( getComputedStyle(elem).width ); // показывает CSS-ширину elem

Почему мы должны использовать свойства-метрики вместо этого? На то есть две причины:

  1. Во-первых, CSS-свойства width/height зависят от другого свойства – box-sizing , которое определяет, «что такое», собственно, эти CSS-ширина и высота. Получается, что изменение box-sizing , к примеру, для более удобной вёрстки, сломает такой JavaScript.
  2. Во-вторых, CSS свойства width/height могут быть равны auto , например, для инлайнового элемента:

 alert( getComputedStyle(elem).width ); // auto 

Есть и ещё одна причина: полоса прокрутки. Бывает, без полосы прокрутки код работает прекрасно, но стоит ей появиться, как начинают проявляться баги. Так происходит потому, что полоса прокрутки «отъедает» место от области внутреннего содержимого в некоторых браузерах. Таким образом, реальная ширина содержимого меньше CSS-ширины. Как раз это и учитывают свойства clientWidth/clientHeight .

…Но с getComputedStyle(elem).width ситуация иная. Некоторые браузеры (например, Chrome) возвращают реальную внутреннюю ширину с вычетом ширины полосы прокрутки, а некоторые (например, Firefox) – именно CSS-свойство (игнорируя полосу прокрутки). Эти кроссбраузерные отличия – ещё один повод не использовать getComputedStyle , а использовать свойства-метрики.

Если ваш браузер показывает полосу прокрутки (например, под Windows почти все браузеры так делают), то вы можете протестировать это сами, нажав на кнопку в ифрейме ниже.

У элемента с текстом в стилях указано CSS-свойство width:300px .

На ОС Windows браузеры Firefox, Chrome и Edge резервируют место для полосы прокрутки. Но Firefox отображает 300px , в то время как Chrome и Edge – меньше. Это из-за того, что Firefox возвращает именно CSS-ширину, а остальные браузеры – «реальную» ширину за вычетом прокрутки.

Обратите внимание: описанные различия касаются только чтения свойства getComputedStyle(. ).width из JavaScript, визуальное отображение корректно в обоих случаях.

Итого

У элементов есть следующие геометрические свойства (метрики):

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

Задачи

Найти размер прокрутки снизу

важность: 5

Свойство elem.scrollTop содержит размер прокрученной области при отсчёте сверху. А как подсчитать размер прокрутки снизу (назовём его scrollBottom )?

Напишите соответствующее выражение для произвольного элемента elem .

P.S. Проверьте: если прокрутки нет вообще или элемент полностью прокручен – оно должно давать 0 .

let scrollBottom = elem.scrollHeight - elem.scrollTop - elem.clientHeight;

Другими словами: (вся высота) минус (часть, прокрученная сверху) минус (видимая часть) – результат в точности соответствует размеру прокрутки снизу.

Узнать ширину полосы прокрутки

важность: 3

Напишите код, который возвращает ширину стандартной полосы прокрутки.

Для Windows она обычно колеблется от 12px до 20px . Если браузер не выделяет место под полосу прокрутки (так тоже бывает, она может быть прозрачной над текстом), тогда значение может быть 0px .

P.S. Ваш код должен работать в любом HTML-документе, независимо от его содержимого.

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

Тогда разница между его полной шириной offsetWidth и шириной внутреннего содержимого clientWidth будет равна как раз прокрутке:

// создадим элемент с прокруткой let div = document.createElement('div'); div.style.overflowY = 'scroll'; div.style.width = '50px'; div.style.height = '50px'; // мы должны вставить элемент в документ, иначе размеры будут равны 0 document.body.append(div); let scrollWidth = div.offsetWidth - div.clientWidth; div.remove(); alert(scrollWidth);

Как добавить элементу полосу прокрутки по вертикали

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

Однако свойство overflow позволяет настроить поведение блока в подобной ситуации и добавить возможность прокрутки. Это свойство может принимать следующие значения:

Рассмотрим применение двух значений:

    Прокрутка в CSS3 .article1 < width: 300px; height: 150px; margin:15px; border: 1px solid #ccc; overflow: auto; >.article2  

Старый дуб, весь преображенный, раскинувшись шатром сочной, темной зелени, млел, чуть колыхаясь в лучах вечернего солнца. Ни корявых пальцев, ни болячек, ни старого недоверия и горя – ничего не было видно. Да, это тот самый дуб», – подумал князь Андрей, и на него вдруг нашло беспричинное весеннее чувство радости и обновления.

Старый дуб, весь преображенный, раскинувшись шатром сочной, темной зелени, млел, чуть колыхаясь в лучах вечернего солнца. Ни корявых пальцев, ни болячек, ни старого недоверия и горя – ничего не было видно. Да, это тот самый дуб», – подумал князь Андрей, и на него вдруг нашло беспричинное весеннее чувство радости и обновления.

Создание прокрутки в CSS

Свойство overflow управляет полосами прокрутки как по вертикали, так и по горизонтали. С помощью дополнительных свойств overflow-x и overflow-y можно определить прокрутку соответственно по горизонтали и по вертикали. Данные свойства принимают те же значения, что и overflow :

overflow-x: auto; overflow-y: hidden;

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

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