Couplage étroit entre Javascript, HTML et CSS: une approche plus moderne?

29

Il est très courant de voir Javascript lié à certains sélecteurs pour trouver des éléments, stocker des données et écouter des événements. Il est également courant de voir ces mêmes sélecteurs utilisés pour le style.

jQuery (et son moteur de sélection Sizzle) prennent en charge et promeuvent cela en référençant les éléments avec une syntaxe de type CSS. En tant que telle, cette technique est particulièrement difficile à «désapprendre» (ou à refactoriser) lors de la construction de projets.

J'en suis venu à comprendre que cela est le résultat de l'histoire du développement HTML et Javascript, et que les navigateurs ont été construits pour consommer / analyser / et rendre efficacement ce type de couplage. Mais comme les sites Web deviennent de plus en plus complexes, cette réalité peut introduire des difficultés dans l'organisation et la maintenance de ces couches distinctes.

Ma question est: cela peut-il et devrait-il être évité dans les sites Web modernes?

Si je suis nouveau dans le développement frontal et que je souhaite apprendre les choses de la bonne manière, cela vaut-il la peine d'apprendre à découpler et à éviter de telles dépendances dès le départ? Est-ce à dire éviter jQuery au profit d'une bibliothèque qui favorise une structure plus découplée?

Stuart Kershaw
la source
1
Comment une telle chose fonctionnerait-elle? Comment, par exemple, désactiver un contrôle sur une page sans vraiment toucher à ce contrôle d'une manière quelconque, ou sans en avoir connaissance? (c'est ma petite façon de dire que vous devez être plus précis sur ce que vous entendez par découplage, idéalement avec quelques exemples, même s'ils sont artificiels).
Robert Harvey
2
La chose la plus importante lorsque vous parlez de découplage html, css et js est d'utiliser des sélecteurs de classe à la place de tout autre, c'est le concept de base de méthodologies comme oocss et BEM.
angvillar
Apprenez les composants React ou Web, et vous n'aurez plus à vous soucier des sélecteurs dans JS.
Andy

Réponses:

35

Il n'y a aucun moyen d'éviter cela. Ils sont couplés car ils interagissent les uns avec les autres. Si votre javascript a l'intention de faire tout type de manipulation DOM, il a besoin d'un moyen de référencer le DOM.

Il existe différentes conventions pour cela.

L'API DOM de niveau 2 fournit les méthodes getElementById, getElementByTagName et getElementsByName. À ce jour, ce sont les chevaux de bataille de tout type de traversée DOM. Tous les autres sélecteurs jQuery plus sophistiqués se résolvent finalement en une combinaison de ceux-ci, et / ou une traversée directe de chaque nœud DOM (c'était la façon de faire getByClassName).

Il n'y a pas d'autre raccourci. Javascript doit savoir quoi faire et où. En règle générale, si un élément a un identifiant ou une classe qui n'est pertinent que dans les scripts, beaucoup de gens le préfixeront avec js-ou un autre indicateur évident.

Une autre convention plus récente est la sélection des attributs de données.

<ul data-myapp-sortable="true">

jQuery('[data-myapp-sortable]').makeSortable();

L'attribut data est généralement utilisé à des fins de script et la sélection à l'aide de cela a un certain sens. L'inconvénient est que cela est plus lent que l'utilisation de getElementById ().

Une autre approche est celle utilisée par angularJS, qui crée un modèle de vue. Dans cette convention, tout type de fonctionnalité de script est spécifié par des attributs spécialement désignés comme ng-disabled ng-hrefet bien d'autres. Vous n'ajoutez pas de sélecteurs dans votre javascript. Le document HTML devient l'autorité principale sur ce qui est scripté et comment, et le javascript fonctionne de manière abstraite. C'est une bonne approche, mais évidemment avec une courbe d'apprentissage plus élevée que les méthodes précédentes. Et encore une fois, la performance doit être considérée.

Mais ne pensez jamais que vous pouvez écrire du HTML interactif et du javascript, et que ces deux parties ne connaissent pas l'autre. Il s'agit davantage de savoir comment limiter les références aux dépendances.

mastaBlasta
la source
2
Réponse brillante, +1. Ne serait-ce que pour avoir mentionné les attributs de données comme mécanisme pour éviter un couplage serré
Fergus In London
3
les attributs de données ne sont pas une panacée. Ils sont très populaires de nos jours et les gens y mettent tout sauf l'évier de la cuisine. Beaucoup de frameworks (par exemple jQuery UI) les utilisent largement. Vous devez être très strict avec l'espace de noms et les autres conventions pour éviter les problèmes. Ils aident à dissocier HTML de JS, mais ils ne facilitent pas nécessairement le débogage.
mastaBlasta
Je n'ai jamais compris pourquoi l'utilisation des classes, des ID et des attributs de données comme hooks et indicateurs d'état devait être réinventée. Tout ce que Angular a accompli à cet égard est une réduction des performances et a remplacé une convention largement connue / comprise par une nouvelle exigeant que l'on comprenne comment le faire "à la manière angulaire", en inventant vos propres attributs et balises. Il n'y a pas de courbe d'apprentissage énorme là-bas. C'est juste plus lent, contrairement à une convention parfaitement raisonnable et connue et à une OMI complètement inutile.
Erik Reppen
9

Si vous êtes prêt à renoncer à l'interactivité que vous obtenez, vous pouvez éviter complètement Javascript. Les frameworks comme ASP.NET MVC sont très bons pour servir des pages qui ne contiennent que du HTML, du CSS et un bouton SUBMIT.

D'ACCORD. C'est peut-être un peu extrême.

Le découplage dans une application Web se produit déjà à plusieurs niveaux. Les applications REST vous permettent de définir votre application en termes de "ressources Web" associées à une URL. Les modèles de vue vous permettent de présenter des données à l'interface utilisateur qui sont découplées du modèle de domaine, mais qui ont la forme dont vous avez besoin pour les afficher correctement. Les couches de service permettent d'échanger une interface utilisateur pour une autre, etc.

Historiquement, il y a toujours eu un compromis entre l'interactivité et le couplage. Plus votre page Web est interactive, plus elle sera étroitement liée à l'application qu'elle sera. Mais la logique d'interactivité dans la page Web est limitée à la page Web elle-même; tout couplage avec le serveur va se produire via POST ou AJAX. Je ne suis donc pas sûr que vous devriez trop vous préoccuper du couplage au niveau Javascript, à part faire attention à la façon dont les paquets de données sont transmis entre le navigateur et le serveur.

L'approche la plus "moderne" (c'est-à-dire la saveur de la semaine) est probablement les applications SPA .

Robert Harvey
la source
Cela ne me semble pas extrême. De nombreux sites qui utilisent largement JavaScript, au point qu'ils sont inutilisables sans, n'en ont pas réellement besoin. Est-ce que leurs développeurs auraient plus d'un indice ...
Michael Hampton
5

Martin Fowler décrit une approche à cela comme le DOM séparé, où vous séparez votre JavaScript DOM de votre JavaScript de logique de page.

Application Logic <----> DOM Manipulation <----> DOM / HTML
Rory Hunter
la source
1
+1 Je suis totalement d'accord avec la ségrégation de la logique DOM <--> JavaScript. Je n'aime vraiment pas les attributs de données car ils ne sont pas pertinents pour le DOM mais pour un outil externe. Je pense qu'une approche plus propre consiste à avoir une sorte de cartographie. Oui, cela peut signifier que vous avez alors un fichier avec des références à deux aspects (par exemple, les fonctions JS et les éléments DOM) plutôt que, par exemple, le DOM contenant certaines références que le JS récupère (ce qui pourrait être décrit comme «à aspect unique»). '). Cependant, si cela est réfléchi, cela peut être très maintenable, réutilisable et offrir une meilleure séparation des préoccupations que les attributs de données.
awj
2

Non, l'utilisation de sélecteurs de classe, d'élément et d'ID côté client ne doit pas être évitée. La syntaxe est utilisée parce que les sélecteurs CSS sont un langage de domaine très mature et bien établi, et avoir une conception commune facilite beaucoup plus le partage d'un modèle logique commun d'une page entre le programme et la conception, ce qui est une très, très bonne chose.

Bien qu'il soit possible de mal utiliser cette syntaxe et de créer une application terrible et impossible à maintenir, cela est possible indépendamment de votre langue ou de votre ensemble d'outils.

DougM
la source
2
Je recommande en fait de ne pas utiliser de sélecteurs de classe, d'élément et d'ID pour de nombreuses choses, et je me concentre plutôt sur l'utilisation de [data-*]sélecteurs d'attributs personnalisés , qui peuvent être utilisés de manière très puissante.
zzzzBov
2
Mauvais conseils dans mon esprit, surtout quand il s'agit d'écrire un JS modulaire / réutilisable qui ne devrait faire aucune hypothèse sur les sélecteurs. Les attributs de données sont une meilleure idée pour ces scénarios.
Fergus à Londres
3
@zzzzBov - Je sais que c'est une microoptimisation, mais les recherches d'ID et de classe sont beaucoup plus rapides que les recherches d'attributs de données. Mais oui, j'aime l'idée d'utiliser différents ensembles d'attributs pour gérer différentes préoccupations.
Jimmy Breck-McKye
0

Quelqu'un doit créer une interface de gestionnaire de chemin jQuery pour une couche d'indirection et de cache vers le dom.

pathMgr.register(name,selector [,isDynamic=false]);
pathMgr.get(name [,refresh]);

Ensuite,

String.prototype.reg([isDynamic=false]);
String.prototype.get(name [,refresh]);

Alors,

// at init....
var pathMgr=new PathMgr();
'sidebar-links #sidebar a'.reg();// new registery of selector '#sidebar a' under name 'sidebar-links'
// more, more


// in code
'sidebar-links'.get().css(etc...);
//or
'sidebar-links'.addStyleRule({});
marque
la source