Как да се преборите с превъртане

„Превъртете се към бъдещето“, зли марсианци - https://evilmartians.com/chronicles/scroll-to-the-future-modern-javascript-css-scrolling-implementations

На първо място - ЗАЩО човек трябва да се бори с свитъка?

Накратко - защото понякога се налага да блокирате всички взаимодействия със страницата. Страницата трябва да бъде напълно безотговорна. Това е правилото. Просто правило.

  • Няма да можете да щракнете върху него. Не можете да щракнете.
  • Преместете фокуса или натиснете клавиши. Не може да натисне.
  • Превъртете го. Не можете да превъртате

Добре тогава - КОГА трябва да е безотговорно?

Когато трябва да се съсредоточите не върху страницата, а само върху някаква част от нея.

Например Модали - малки (или големи) кутии, плаващи в средата на екрана. Останалата част от страницата може да бъде дори затъмнена, защото…

Modal е единственото образувание, с което трябва да работите.
Modal ще блокира всичко, това е https://atlaskit.atlassian.com/packages/core/modal-dialog

Малко съм изненадан, че MDN Modal Dialog a11n Article подчертава необходимостта от управление на фокуса и атрибути от правилната ария, но не и блокиране на превъртането.

И не блокиране на текст в реч чрез инертна или ария скрита, в момента се прилага само в обхвата на достъпа и гладкото

Може би не е много ясно защо модалът трябва да блокира превъртането на страницата. Извиването изглежда е наред, стига да го виждате.

Докато разбирате какво превъртате страницата. И докато е това, което сте искали да направите.

По този начин друг чудесен пример за обяснение защо превъртането трябва да бъде блокирано, е модулен диалогов прозорец на цял екран или „FocusedTask“. Нещо, което ще консумира цялото ви внимание.

Всъщност - това е лош пример (https://www.w3schools.com/howto/howto_js_fullscreen_overlay.asp)

Веднъж отворена, тя ще консумира целия екран и вече няма да виждате и няма да можете да взаимодействате със съдържанието на основната страница. Но вие ще можете да го превъртите.

Нуждаете се от повече? Ок - компонент „onboarding“, който ви ориентира към страницата.

AtlasKit „onboarding“ е страхотно - https://atlaskit.atlassian.com/packages/core/onboarding

Нека си представим - вие сте в състояние да превъртите страницата. И ще превъртите страницата. И „прожекторите“ ще бъдат превъртани. И вашият клиент ще бъде загубен в частично забраненото приложение ...

Как да блокирам превъртане?

О! Това е супер лесно - style = "overflow: скрит" на тялото.

overflow: скрито ще премахне лентите за превъртане (те са скрити) и ще блокира превъртането, стига този режим на препълване да не се превърта. Ето как работи CSS.

Готово. Може да се приберете вкъщи.

Но ... Сафари

Да - това не работи на Mobile Safari.

Изненада!

  • Safari игнорира преливането по тялото, което ви позволява да го докоснете-превъртете. И това е нещо, което можете да докоснете-n-усетите само в реалния iPhone, а не в емулация на Chrome.
  • Той ще работи като глупост, особено за формите, докато продължителното „превъртане с докосване“ е действие „плъзгане-пускане“ за някои тагове и няма да можете да превъртите мисълта за тях.

Коригирането на втория проблем е просто - просто променете поведението на превъртане:

> Това може да е нещо, което искате да бъде активирано по подразбиране!

И коригирането на първия проблем е също ... просто ... - event.preventDefault.

Единственият проблем - кой елемент да слушате и кое събитие да предотвратите. Всички събития вътре в модала трябва да преминат в живота, всички събития навън трябва да бъдат блокирани и всички тези събития могат да бъдат балон от „ок-иш” елементи, до не-ок-иш.

Така че - за всяко събитие, което може да причини превъртане, трябва да изчислите нещо, да го наречете превъртаемост и да блокира събитие, което може да превърта нещо, което не искате да бъде превъртано.

Бих казал - използвайте външни библиотеки, за да се справите с това.

заключение

Така че - използвайте overflow: скрит върху тялото, за да убиете превъртането в браузърите на Desktop и Android и да предотвратите събитията, за да смекчите Safari.

Лесно?

Всъщност не, пропуснахме една точка. Скрол ленти!

Убийте лентата за превъртане!

Превъртането е забранено само когато лентите за превъртане са деактивирани.

Въпрос - имахте лента за превъртане и сега сте я премахнали. Това е останало?

Лентите за превъртане изчезнаха! Напълно!
Нямам машина за Windows, съжалявам

В резултат на това вие отваряте страница с 17 пиксела по-широко и цялото ви съдържание „скочи“. Този паразит и доста неприятен трептящ ефект няма да издържаме.

Лесно е да го смекчите - открийте ширината на лентата за превъртане, зададена като подплънка към тялото.

И последно „бонус“ неща - правилно боравейте с ширината на тялото: нормалните елементи трябва да имат „точно“ там, както беше преди, т.е. с „празнина“, докато „дясно“ за елементите вътре в ключалката трябва да е отдясно на прозореца.

Попълване на „празнина“ с paddingRight.

Забележка - абсолютните позиционирани елементи се придържат към ръба на прозореца. Това може да е нещо, което искате - да показвате елемент от ръба до ръба. Но, знаете, съдържанието на тези елементи ще се „разклати“ и вероятно това не е това, което наистина искате.

Попълване на „празнината“ с marginRight.

Забележете - първият (червен) и третият (без име) елемент не променят позицията си, докато вторият (позиция: фиксиран) все още се придържа към ръба. Това е поправимо - стига да „фиксираме“ тялото - може да фиксираме всеки друг елемент.

Вероятно имате нужда от това поведение.
Забавен факт - повечето библиотеки използват подплънки. Някакви идеи защо?

Днес има само една библиотека (и за съжаление - тя се основава на React, не се колебайте да я разклоните и приемете в стека си), което прави правилно:

Друг извод

Стъпка за предотвратяване на превъртане върху елемент :

  • Добавяне на преливник: скрит върху елемента на тялото.
  • Работете със сензорни събития, за Safari.
  • Запазете празнината на лентата за превъртане.

Плюс бонус точка: накарайте заключването на цял екран да работи без „празнина“.

И, да бъда честен, това не е толкова лесно, колкото 1–2–3. Детайли, дяволът е в подробности. Моля, използвайте библиотеки на трети страни - те ще ви помогнат. Много! Както обикновено.

Прочети

Прочетете повече за проблемите с превъртането и превъртането. Това е най-добрата статия някога.

Прочетете повече за анулирането на събития за превъртане / колело / докосване

И не забравяйте за "правилното управление на фокуса", споменах в статията в началото, но не обясних правилно:

употреба

DOM (Vanilla JS)

Body-scroll-lock: ще обхване всички 3 стъпки. Цитат компактен. Позволява вътрешен превъртащ се елемент вътре, което може да доведе до истински проблем с производството. Вероятно не бих го препоръчал, но аз пиша тази статия поради статия за тази библиотека, така че - благодаря ви body-scroll-lock.

Scroll-lock: Ще обхване всички 3 стъпки, включително вложени контейнери за превъртане и конфигурируеми нужди, за да отговарят на всяка нужда. Тази библиотека получи само няколко ️, но струва милион.

Дом-Локи: обработва само дори „предотвратяваща“ стъпка, но прави правилно. Вие сами обработвах лентата за превъртания и се нуждаете само от събития с докосване - използвайте тази библиотека.

реагирам

React-scroll-locky: пълнофункционална библиотека за покриване на 3 стъпки. Поддръжка на вложени ключалки, вложени компоненти за превъртане и абсолютно нечупливи.

React-remove-scroll: друга версия на scroll-locky, два пъти по-малки и осъзнати портали (вероятно това е най-добрият избор за React)

React-scrolllock: пълнофункционална библиотека за покриване на 3 стъпки. Не поддържа вложени вградени ключалки, вложени компоненти за превъртане, портали и използва подплънки на тялото. Но трябва да го спомена, стига да съм създал моите като отговор на този.

екстра

Лентите за превъртане са счупени. Това е факт. Ето защо трябва да ги крием, докато трябва да ги деактивираме. Не всички браузъри ви позволяват да ги контролирате. Не всички браузъри дори ги имат. Вземете съдбата си в свои ръце -