În prima parte a acestei călătorii Draggable, am discutat despre cum să includem scripturi, să investigăm ThrowPropsPlugin, inclusiv cerințele de a începe proiectul în speranța de a ajunge la unsprezece! Acum, pregateste-te sa faci un sistem de meniuri off-panza care reactioneaza la tastatura si atinge.
Demo-ul complet pe care îl vom construi și discutăm pentru restul acestui tutorial este disponibil și pe CodePen.
Vă încurajez să încercați acest lucru pentru dvs. pe cât mai multe dispozitive posibil, în special navigarea pe tastatură. Fiecare interacțiune - fie atingere, tastatură sau mouse-a fost luată în considerare, dar după cum veți descoperi în peisajul nostru actual nu puteți detecta un ecran tactil și uneori încercarea de a face acest lucru chiar dă rezultate false.
Folosind marcajul din partea I vom începe prin adăugarea unui container div
pentru scopuri structurale, împreună cu clase de corelare pentru cârligele CSS și JavaScript.
... ...
Clasele care încep cu prefixul "js" înseamnă că aceste clase apar doar în JavaScript; eliminarea acestora ar împiedica funcționarea. Nu sunt folosite niciodată în CSS, ajutând la izolarea preocupărilor. Containerul înconjurător vă va ajuta să controlați comportamentul de derulare care este discutat în secțiunea CSS viitoare.
Cu fundația în loc este timpul să adăugați un strat de ARIA pe partea de sus pentru a împrumuta sensul semantic pentru a citi cititorii și utilizatorii tastaturii.
Din moment ce meniul va fi ascuns în mod implicit Aria-ascuns
atributul este etichetat Adevărat
și va fi actualizat corespunzător în funcție de starea meniului; fals
pentru deschidere, Adevărat
pentru închis. Iată o explicație a atributului Aria-ascuns
conform specificației W3C:
Indică faptul că elementul și toți descendenții săi nu sunt vizibili sau percepuți de nici un utilizator, așa cum este pus în aplicare de către autor. [...] Autorii TREBUIE setați aria-hidden = "true" pentru conținutul care nu este afișat, indiferent de mecanismul folosit pentru a-l ascunde. Acest lucru permite tehnologiilor de asistență sau agenților utilizator să ignore elementele ascunse în document. ~ W3C WAI-ARIA Spec
Autorii ar trebui să fie atent ce conținut ascunde, făcând acest atribut o discuție separată în afara domeniului de aplicare al acestui articol. Pentru cei curiosi, caietul de sarcini defineste atributul cu o lungime mai mare si este oarecum grockabil; ceva ce nu spun, de obicei, de multe ori despre jargonul specificat.
CSS este locul unde magia începe cu adevărat. Să luăm piesele importante din demo care poartă semnificație și o descompun.
corp // scroll fix height: 100%; overflow: ascuns; // end scroll fix .app // scroll fix overflow-y: defilați; înălțime: 100vh; // end scroll fix .dragaebel-nav înălțime: 100vh; overflow-y: auto; poziție: fixă; top: 0; dreapta: 0;
Stabilirea înălțimii corpului la 100% permite containerului să întindă întregul port de vizualizare, dar, de asemenea, joacă un rol mai important; permițându-ne să ascundem depășirea.
Suportul de deplasare pentru depășire vă ajută să controlați modul în care containerul primar și navigația se comportă atunci când unul conține conținut învechit. De exemplu, dacă containerul este derulat - sau meniul - celălalt nu va derula atunci când utilizatorul ajunge la sfârșitul elementului derulat inițial. Este un comportament ciudat, care nu este discutat în mod obișnuit, dar duce la o experiență mai bună a utilizatorului.
Unitățile de vizualizare sunt cu adevărat puternice și joacă un rol vital în modul în care containerul primar deține conținut învechit. Unitățile Viewport au în aceste zile suport minunat în toate browserele și vă recomand să începeți să le utilizați. Am folosit unități vh pe nav, dar aș fi putut folosi un procent. În timpul dezvoltării sa descoperit că div.app
trebuie să utilizeze vh
deoarece procentajul nu va permite ca conținutul care se deplasează să mențină comportamentul tipic de defilare; conținutul duce la tăierea. Deplasarea este setată la sul
în pregătire, în cazul în care elementele de meniu depășesc înălțimea meniului sau înălțimea ferestrei de vizualizare devine îngustă.
// Permite nav să se deschidă atunci când JS nu reușește .no-js .dragaebel-nav: țintă marginea-dreapta: 0; .dragaebel-nav marginea-dreapta: -180px; lățime: 180px;
.nu-js .nav: țintă
oferă acces la meniul nostru, indiferent dacă JavaScript nu reușește sau este dezactivat, motiv pentru care am adăugat valoarea ID la href
atributul declanșatorului de meniu.
Navigarea primară este deplasată spre dreapta printr-o margine negativă care este, de asemenea, aceeași cu lățimea navei. Din motive de coincidență scriu Vanilla CSS, dar sunt sigur că ai putea scrie ceva cochet într-un pre-procesor la alegerea ta.
JavaScript este ultima oprire a acestei călătorii cu meniuri, dar înainte de a scrie o linie de JS va trebui să scriem o configurare a modulului.
var dragaebelMenu = (functie () functie doSomething () ... retur init: function () ...) (); dragaebelMenu.init (); // incepe!
Pentru configurarea configurației vom defini câteva variabile pentru referințe ulterioare.
var dragaebelMenu = (funcție () var container = document.querySelectorAll ('.js-dragsurface') [0], nav = document.querySelectorAll (' .js-dragtoggle ') [0], logo = document.querySelectorAll (' .js-draglogo ') [0], gs_targets = [container, nav, logo, nav_trigger], closed_nav = nav.offsetWidth + getScrollBarWidth ) ();
Cele mai multe dintre aceste variabile sunt pur și simplu grabbing DOM
elemente, cu excepția ultimelor două care definesc obiectivele noastre GreenSock plus lățimea meniului de navigare. Funcția de utilitate getScrollBarWidth ()
(în afara discuției noastre de astăzi) preia lățimea barei de derulare, astfel încât să putem poziționa nava chiar dincolo de lățimea barei, pentru ao vedea când se deschide meniul. Obiectivele sunt ceea ce ne mișcă când se deschide meniul pentru a permite împingerea conținutului adiacent.
Pentru a păstra lucrurile scurte, voi discuta doar metode care sunt extrem de importante pentru funcționalitatea comportamentului meniului. Tot ceea ce veți vedea în demo nu este discutat aici este chestii de "zahăr de sus" care fac meniul chiar mai puternic.
meniul funcțional (durata) container._gsTransform.x === -closed_nav? TweenMax.to (gs_targets, durata, x: 0, ușurință: Linear.easeIn): TweenMax.to (gs_targets, duration, x: -closed_nav, ease: Linear.easeOut);
meniul
funcția detectează dacă coordonatele x ale containerului sunt egale cu starea nav deschisă. Dacă așa se stabilește țintele înapoi în poziția lor de pornire, altfel le fixează în poziția lor deschisă.
funcția isOpen () return container._gsTransform.x < 0;
Aceasta este o funcție de utilitate pentru a verifica starea meniului. Aceasta se va întoarce 0
dacă meniul este închis sau o valoare negativă dacă este deschisă.
funcția updateNav (eveniment) TweenMax.set ([nav, logo, nav_trigger], x: container._gsTransform.x);
Aceasta este o altă funcție utilitară care stabilește coordonatele x ale țintă în interiorul parametrului array al lui .a stabilit()
metoda pentru poziția x a containerului în fiecare zi onDrag
sau onThrowUpdate
evenimentul se întâmplă. Aceasta face parte din draggable
obiect instanță.
funcția enableSelect () container.onselectstart = null; // Se aprinde atunci când obiectul este selectat. Setul TweenMax.set (container, userSelect: 'text'); funcția disableSelect () TweenMax.set (container, userSelect: 'none'); funcția esteSelecting () // window.getSelection: Returnează un obiect de selecție reprezentând // intervalul de text selectat de utilizator sau poziția curentă // a cartelei. întoarce !! window.getSelection () la toString () lungime;
Aceste funcții ajută la determinarea faptului că cineva selectează într-adevăr un text pentru a permite / debloca capacitățile de selecție atunci când cineva trage pe ecran. Acesta nu este cel mai ideal comportament pentru evenimentele mouse-ului, dar din nou, așa cum am menționat deja, nu puteți detecta un ecran tactil.
Draggable.create ([țintă], opțiuni)
Așa cum am discutat în tutorialul anterior despre Draggable, acesta va crea instanța obiectului Draggable și va viza DOM
obiectele alese de noi, care pot fi transferate ca o matrice.
Draggable.create ([container], tip: 'x', dragClickables: false, throwProps: true, dragResistance: 0.025, edgeResistance: 0.99999999, maxDuration: 0.25, throwResistance: 2000, cursor: 'resize', allowEventDefault: : ..., onDrag: updateNav, onDragEnd: functie (eveniment) ..., liveSnap: functie (valoare) ..., onPress: : funcția () ...);
Aceasta este întreaga noastră instanță trasabilă și proprietățile utilizate. Codul demo real conține comentariile pe care le-am lăsat pentru a înțelege și a obține o perspectivă mai bună asupra a ceea ce este responsabil de fiecare. Vă încurajez să examinați codul demo și chiar să vă provocați să deconstruiți de ce și cum.
Acesta este sfârșitul călătoriei noastre GreenSock și sper că ați învățat o tona de-a lungul drumului. Mulțumiri deosebite lui Jack și Carl de la GreenSock, împreună cu întreaga comunitate GreenSock, pentru ajutorul lor incredibil pe parcursul acestei serii. Nu în ultimul rând, o mare mulțumire pentru dvs., cititorul pentru atingerea sfârșitului acestei serii; felicitări! Sper că această serie a ajutat la o mai bună analiză a avantajelor și capabilităților puternice ale unei minunate biblioteci de animație JavaScript. Creați lucruri minunate și rămâneți creativi!