Dans la première partie de ce périple draggable, nous avons expliqué comment inclure des scripts, étudié le ThrowPropsPlugin, y compris les conditions requises pour lancer notre projet dans l’espoir de le mener à onze! Maintenant, préparez-vous à créer un système de menus hors toile qui réagit au clavier et au toucher.
La démo complète que nous allons construire et discuter pour le reste de ce tutoriel est également disponible sur CodePen.
Je vous encourage à tester cela vous-même sur autant d'appareils que possible, en particulier la navigation au clavier. Chaque interaction (tactile, clavier ou souris) a été prise en compte, mais comme vous le constaterez dans notre paysage actuel, vous ne pouvez pas détecter un écran tactile et même tenter de le faire aboutit à des résultats faussement positifs..
En utilisant le balisage de la partie I, nous allons commencer par ajouter un conteneur div
à des fins structurelles avec des classes de corrélation pour les hooks CSS et JavaScript.
……
Les classes commençant par le préfixe «js» signifient que ces classes n'apparaissent qu'en JavaScript; les supprimer entraverait la fonctionnalité. Ils ne sont jamais utilisés en CSS, ce qui aide à isoler le centre des préoccupations. Le conteneur environnant aidera à contrôler le comportement de défilement, ce qui est discuté dans la prochaine section CSS.
Avec la fondation en place, il est temps d'ajouter une couche d'ARIA pour donner un sens sémantique aux lecteurs d'écran et aux utilisateurs de clavier..
Comme le menu sera masqué par défaut, le aria-caché
attribut est étiqueté vrai
et sera mis à jour en conséquence en fonction de l'état du menu; faux
pour ouvrir, vrai
pour fermé. Voici une explication de l'attribut aria-caché
selon la spécification W3C:
Indique que l'élément et tous ses descendants ne sont visibles ou perceptibles par aucun utilisateur, comme implémenté par l'auteur. […] Les auteurs DOIVENT définir aria-hidden = "true" sur le contenu non affiché, quel que soit le mécanisme utilisé pour le masquer. Cela permet aux technologies d'assistance ou aux agents utilisateurs de ignorer correctement les éléments cachés du document. ~ Spéc. WAI-ARIA du W3C
Les auteurs doivent faire attention au contenu qu'ils cachent, faisant de cet attribut une discussion distincte qui sort du cadre de cet article. Pour les curieux, la spécification définit l'attribut dans une longueur supplémentaire et est quelque peu grokkable; quelque chose que je ne dis pas souvent que souvent sur le jargon de spécification.
Notre CSS est où la magie commence vraiment. Prenons les parties importantes de la démo qui ont un sens et décomposons-les.
body // scroll fix height: 100%; débordement caché; // fin du correctif de défilement .app // correctif de défilement overflow-y: scroll; hauteur: 100vh; // fin du correctif de défilement .dragaebel-nav height: 100vh; débordement-y: auto; position: fixe; en haut: 0; à droite: 0;
Définir la hauteur du corps à 100% permet au conteneur d’étirer la totalité de la fenêtre de visualisation, mais joue également un rôle plus important; nous permettant de cacher son débordement.
Le correctif de défilement de débordement permet de contrôler le comportement du conteneur principal et de la navigation lorsque l'un ou l'autre contient du contenu débordant. Par exemple, si le conteneur fait défiler ou le menu, l'autre ne défilera pas lorsque l'utilisateur aura atteint la fin de l'élément initialement défilé. C'est un comportement étrange, pas typiquement discuté, mais qui permet une meilleure expérience utilisateur.
Les unités de fenêtre de visualisation sont vraiment puissantes et jouent un rôle essentiel dans la manière dont le conteneur principal contient le contenu débordant. Les unités de Viewport offrent un support formidable sur les navigateurs de nos jours et je vous suggère fortement de commencer à les utiliser. J'ai utilisé des unités vh sur le nav, mais j'aurais pu utiliser un pourcentage à la place. Au cours du développement, il a été découvert que div.app
doit utiliser vh
les unités, car le pourcentage ne permettra pas au contenu débordant de conserver un comportement de défilement typique; le contenu est tronqué. Le débordement est défini sur faire défiler
en cours de préparation si les éléments du menu dépassent la hauteur du menu ou la hauteur de la fenêtre deviennent trop étroits.
// Autoriser la navigation à s'ouvrir lorsque JS échoue .no-js .dragaebel-nav: target margin-right: 0; .dragaebel-nav marge-droite: -180px; largeur: 180px;
le .no-js .nav: cible
permet d'accéder à notre menu, que JavaScript échoue ou soit désactivé ou non, d'où la raison pour laquelle nous avons ajouté la valeur ID au href
attribut du déclencheur de menu.
La navigation principale est déplacée vers la droite via une marge négative qui correspond également à la largeur de la navigation. Par souci de brièveté, j'écris Vanilla CSS, mais je suis sûr que vous pourriez écrire quelque chose de plus sophistiqué dans un pré-processeur de votre choix..
JavaScript est la dernière étape de ce parcours de menu déplaçable, mais avant d'écrire une ligne de JS, nous devons écrire une configuration de modèle de module..
var dragaebelMenu = (function () function doQuelque chose () … return init: function () …) (); dragaebelMenu.init (); // commence le!
Pour la configuration, nous allons définir des variables pour référence future.
var dragaebelMenu = (function () var conteneur = document.querySelectorAll ('. js-dragsurface') [0], nav = document.querySelectorAll ('. js-dragnav') [0], nav_trigger = document.querySelectorAll (' .js-dragtoggle ') [0], logo = document.querySelectorAll ('. js-draglogo ') [0], gs_targets = [conteneur, nav, logo, nav_trigger], closed_nav = nav.offsetWidth + getScrollBarWidth (); ) ();
La plupart de ces variables sont simplement saisir DOM
éléments, à l’exception des deux derniers qui définissent nos cibles GreenSock plus la largeur du menu de navigation. La fonction utilitaire getScrollBarWidth ()
(en dehors de notre discussion d’aujourd’hui) récupère la largeur de la barre de défilement afin que nous puissions positionner la barre de navigation juste au-delà de la largeur de la barre elle-même afin de la voir à l’ouverture du menu. Les cibles sont ce que nous déplaçons lorsque le menu s'ouvre afin de permettre au contenu adjacent d'être poussé.
Pour rester bref, je ne parlerai que des méthodes extrêmement importantes pour la fonctionnalité du comportement du menu. Tout le reste que vous verrez dans la démo et non discuté ici est le "sucre en haut" qui rend le menu encore plus puissant..
menu de fonction (durée) conteneur._gsTransform.x === -closed_nav? TweenMax.to (gs_targets, durée, x: 0, facilité: Linear.easeIn): TweenMax.to (gs_targets, durée, x: -closed_nav, facilité: Linear.easeOut);
le menu
La fonction détecte si la coordonnée x du conteneur est égale à l'état de navigation fermé. Si tel est le cas, les cibles reviennent à leur position de départ, sinon, elles les positionnent à leur position ouverte.
fonction isOpen () return container._gsTransform.x < 0;
Ceci est une fonction utilitaire permettant de vérifier l'état du menu. Cela va retourner 0
si le menu est fermé ou une valeur négative s'il est ouvert.
function updateNav (event) TweenMax.set ([nav, logo, nav_trigger], x: container._gsTransform.x);
Ceci est une autre fonction utilitaire qui définit la coordonnée x de la cible dans le paramètre array de la .ensemble()
méthode à la position x du conteneur à chaque fois la onDrag
ou onThrowUpdate
événement se produit. Cela fait partie de la Glissable
instance d'objet.
function enableSelect () container.onselectstart = null; // Se déclenche lorsque l'objet est sélectionné. TweenMax.set (conteneur, userSelect: 'text'); function disableSelect () TweenMax.set (conteneur, userSelect: 'aucun'); function isSelecting () // window.getSelection: retourne un objet Selection représentant // la plage de texte sélectionnée par l'utilisateur ou la position actuelle // du caret. return !! window.getSelection (). toString (). length;
Ces fonctions permettent de déterminer si une personne sélectionne réellement du texte afin d'activer / désactiver les capacités de sélection lorsqu'une personne traîne à l'écran. Ce n'est pas le comportement idéal pour les événements de souris, mais encore une fois, comme nous l'avons déjà mentionné, vous ne pouvez pas détecter un écran tactile.
Draggable.create ([cibles], options)
Comme nous l'avons vu dans le précédent tutoriel sur Draggable, cela créera l'occurrence de l'objet Draggable et ciblera le DOM
objets de notre choix qui peuvent être passés sous forme de tableau.
Draggable.create ([conteneur], type: 'x', dragClickables: false, throwProps: true, dragResistance: 0.025, edgeResistance: 0.99999999, maxDuration: 0.25, throwResistance: 2000, curseur: 'resize', allowEventDefault: true, bounds : …, OnDrag: updateNav, onDragEnd: fonction (événement) …, liveSnap: fonction (valeur) …, onPress: fonction (événement) …, onClick: fonction (événement) …, onThrowUpdate : une fonction() … );
Ceci est notre instance Draggable entière et les propriétés utilisées. Le code de démonstration contient des commentaires que j'ai laissés afin de comprendre et de mieux comprendre la responsabilité de chacun. Je vous encourage à regarder dans le code de démonstration et même à vous défier de déconstruire le pourquoi et le comment.
C’est la fin de notre aventure GreenSock et j’espère que vous en aurez appris beaucoup plus en chemin. Un merci spécial à Jack et Carl de GreenSock, ainsi qu’à toute la communauté GreenSock, pour leur aide incroyable tout au long de cette série. Enfin et surtout, un grand merci à vous, lecteur, d’avoir atteint la fin de cette série; félicitations! J'espère que cette série a permis de mieux comprendre les puissants avantages et capacités d'une bibliothèque d'animations JavaScript géniale. Construisez des choses géniales et restez créatif!