Enge Kopplung zwischen Javascript, HTML und CSS: Ein moderner Ansatz?

29

Es ist weit verbreitet, dass Javascript an bestimmte Selektoren gebunden ist, um Elemente zu finden, Daten zu speichern und auf Ereignisse zu warten. Es ist auch üblich, dieselben Selektoren für das Styling zu verwenden.

jQuery (und seine Selector Engine Sizzle) unterstützen und fördern dies, indem sie auf Elemente mit CSS-Syntax verweisen. Daher ist es besonders schwierig, diese Technik beim Erstellen von Projekten zu „verlernen“ (oder neu zu faktorisieren).

Ich habe verstanden, dass dies ein Ergebnis der Entwicklung von HTML und Javascript ist und dass Browser so konstruiert wurden, dass sie diese Art der Kopplung effizient verarbeiten / analysieren / und rendern. Da Websites jedoch immer komplexer werden, kann dies zu Schwierigkeiten bei der Organisation und Verwaltung dieser separaten Ebenen führen.

Meine Frage ist: Kann und sollte dies auf modernen Websites vermieden werden?

Wenn ich neu in der Front-End-Entwicklung bin und die Dinge auf die richtige Weise lernen möchte, lohnt es sich dann zu lernen, solche Abhängigkeiten von Anfang an zu entkoppeln und zu vermeiden? Bedeutet dies, jQuery zugunsten einer Bibliothek zu vermeiden, die eine entkoppelte Struktur fördert?

Stuart Kershaw
quelle
1
Wie würde so etwas funktionieren? Wie können Sie zum Beispiel ein Steuerelement auf einer Seite deaktivieren, ohne dieses Steuerelement zu berühren oder zu kennen? (Dies ist meine Art zu sagen, dass Sie genauer definieren müssen, was Sie unter Entkoppeln verstehen, idealerweise mit einigen Beispielen, auch wenn sie erfunden sind).
Robert Harvey
2
Das Wichtigste, wenn Sie über das Entkoppeln von HTML, CSS und JS sprechen, ist die Verwendung von Klassenselektoren anstelle anderer. Dies ist das Kernkonzept von Methoden wie OOCSS und BEM.
Angvillar
Lernen Sie React oder Webkomponenten und Sie müssen sich nicht mehr mit Selektoren in JS befassen.
Andy

Antworten:

35

Daran führt kein Weg vorbei. Sie sind gekoppelt, weil sie miteinander interagieren. Wenn Ihr Javascript beabsichtigt, irgendeine Art von DOM-Manipulation durchzuführen, muss es eine Möglichkeit geben, auf das DOM zu verweisen.

Es gibt verschiedene Konventionen dafür.

Die DOM-API der Ebene 2 stellt die Methoden getElementById, getElementByTagName und getElementsByName bereit. Bis heute sind dies die Arbeitspferde jeder Art von DOM-Durchquerung. Alle anderen fancier jQuery-Selektoren werden schließlich in eine Kombination dieser aufgelöst und / oder durchlaufen jeden DOM-Knoten direkt (dies war der Weg, um getByClassName auszuführen).

Es gibt keine andere Verknüpfung. Javascript muss wissen, was zu tun ist und wo. Wenn ein Element eine ID oder Klasse hat, die nur für die Skripterstellung relevant ist, wird ihr in der Regel von vielen Personen ein js-oder ein anderes offensichtliches Flag vorangestellt .

Eine andere neuere Konvention ist die Auswahl von Datenattributen.

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

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

Das Datenattribut wird im Allgemeinen für Skriptzwecke verwendet, und die Auswahl mit diesem Attribut ist sinnvoll. Der Nachteil ist, dass dies langsamer ist als die Verwendung von getElementById ().

Ein anderer Ansatz ist der von angularJS, der ein Ansichtsmodell erstellt. In dieser Konvention wird jede Art von Skriptfunktionalität durch speziell bezeichnete Attribute wie ng-disabled ng-hrefund viele mehr spezifiziert . Sie fügen Ihrem Javascript keine Selektoren hinzu. Das HTML-Dokument wird zur Hauptautorität für das, was und wie geskriptet wird, und das Javascript arbeitet abstrakt daran. Es ist ein guter Ansatz, aber offensichtlich mit einer höheren Lernkurve als die vorherigen Methoden. Und wieder muss die Leistung berücksichtigt werden.

Aber denken Sie niemals daran, dass Sie interaktives HTML und Javascript schreiben können und irgendwie wissen beide Teile nichts über die anderen. Es geht eher darum, wie Sie die Verweise auf Abhängigkeiten beschränken können.

mastaBlasta
quelle
2
Geniale Antwort, +1. Wenn auch nur zur Erwähnung von Datenattributen als Mechanismus zur Vermeidung einer engen Kopplung
Fergus In London
3
Datenattribute sind kein Allheilmittel. Sie sind heutzutage sehr beliebt und die Leute setzen alles außer dem Spülbecken ein. Viele Frameworks (z. B. jQuery UI) verwenden sie in großem Umfang. Sie müssen mit Namespaces und anderen Konventionen sehr streng umgehen, um Probleme zu vermeiden. Sie helfen dabei, HTML von JS zu entkoppeln, machen das Debuggen jedoch nicht unbedingt einfacher.
MastaBlasta
Ich habe nie verstanden, warum die Verwendung von Klassen, IDs und Datenattributen als Hooks und Statusflags neu erfunden werden musste. Alles, was Angular in dieser Hinsicht erreicht hat, ist eine Leistungsreduzierung und ersetzt die allgemein bekannte Konvention durch eine neue, bei der man verstehen muss, wie man es "auf die Angular-Art" macht und seine eigenen Attribute und Tags erfindet. Es gibt dort keine große Lernkurve. Es ist nur langsamer, im Gegensatz zu völlig vernünftigen und allgemein bekannten Konventionen und völlig unnötigen IMO.
Erik Reppen
9

Wenn Sie bereit sind, auf die Interaktivität zu verzichten, die Sie erhalten, können Sie Javascript vollständig vermeiden. Frameworks wie ASP.NET MVC können sehr gut Seiten bereitstellen, die nur HTML, CSS und eine SUBMIT-Schaltfläche enthalten.

OKAY. Vielleicht ist das ein bisschen extrem.

Die Entkopplung in einer Webanwendung erfolgt bereits auf vielen Ebenen. Mit REST-Anwendungen können Sie Ihre Anwendung anhand von "Webressourcen" definieren, die einer URL zugeordnet sind. Mit „Modelle anzeigen“ können Sie der Benutzeroberfläche Daten präsentieren, die vom Domänenmodell entkoppelt sind, aber die Form haben, die Sie für die ordnungsgemäße Anzeige benötigen. Mit Service-Layern kann eine Benutzeroberfläche gegen eine andere ausgetauscht werden, und so weiter.

Historisch gesehen gab es immer einen Kompromiss zwischen Interaktivität und Kopplung. Je interaktiver Ihre Webseite ist, desto enger ist sie an die jeweilige Anwendung gekoppelt. Die Interaktivitätslogik in der Webseite ist jedoch auf die Webseite selbst beschränkt. Jede Kopplung mit dem Server erfolgt entweder über POST oder AJAX. Ich bin mir daher nicht sicher, ob Sie sich übermäßig mit der Kopplung auf JavaScript-Ebene befassen sollten, außer der Art und Weise, wie Datenpakete zwischen dem Browser und dem Server übertragen werden.

Der "modernste" Ansatz (dh der Geschmack der Woche) sind wahrscheinlich SPA-Anwendungen .

Robert Harvey
quelle
Klingt für mich nicht extrem. Viele Websites, die JavaScript in großem Umfang verwenden und ohne JavaScript unbrauchbar werden, benötigen es nicht. Hätten ihre Entwickler mehr Ahnung ...
Michael Hampton
5

Martin Fowler beschreibt einen Ansatz dazu als " Getrenntes DOM" , bei dem Sie Ihr DOM-JavaScript von Ihrem Seitenlogik-JavaScript trennen.

Application Logic <----> DOM Manipulation <----> DOM / HTML
Rory Hunter
quelle
1
+1 Ich bin mit der Trennung der JavaScript <-> DOM-Logik einverstanden. Ich mag keine Datenattribute, da diese nicht für das DOM relevant sind, sondern für ein externes Tool. Ich bin der Meinung, dass ein sauberer Ansatz darin besteht, eine Art Mapping zu haben. Ja, dies kann bedeuten, dass Sie dann eine Datei mit Verweisen auf zwei Aspekte (z. B. JS-Funktionen und DOM-Elemente) haben und nicht z. B. das DOM, das einige Verweise enthält, die der JS aufnimmt (was als "einzelner Aspekt" beschrieben werden könnte) '). Wenn dies jedoch sorgfältig durchgeführt wird, kann dies sehr wartbar und wiederverwendbar sein und eine bessere Trennung von Bedenken als Datenattribute bieten.
Awj
2

Nein, die clientseitige Verwendung von Klassen-, Element- und ID-Selektoren sollte nicht vermieden werden. Die Syntax wird verwendet, da CSS-Selektoren eine sehr ausgereifte und gut etablierte Domänensprache sind und ein gemeinsames Design die gemeinsame Nutzung eines gemeinsamen logischen Seitenmodells zwischen Programm und Design erheblich erleichtert. Dies ist eine sehr, sehr gute Sache.

Während es möglich ist, diese Syntax zu missbrauchen und eine schreckliche und nicht wartbare Anwendung zu erstellen, ist dies unabhängig von Ihrer Sprache oder Ihrem Toolset möglich.

DougM
quelle
2
Ich empfehle eigentlich, für viele Dinge [data-*]keine Klassen-, Element- und ID-Selektoren zu verwenden, und konzentriere mich stattdessen auf die Verwendung benutzerdefinierter Attributselektoren, die auf sehr leistungsstarke Weise verwendet werden können.
zzzzBov
2
Meiner Meinung nach ein schlechter Rat, insbesondere beim Schreiben von modularen / wiederverwendbaren JS, bei denen keine Auswahl getroffen werden sollte. Datenattribute sind für diese Szenarien eine bessere Idee.
Fergus In London
3
@zzzzBov - Ich weiß, dass es sich um eine Mikrooptimierung handelt, aber die Suche nach IDs und Klassen ist viel schneller als die Suche nach Datenattributen. Aber ja, ich mag die Idee, verschiedene Sätze von Attributen zu verwenden, um mit unterschiedlichen Anliegen umzugehen.
Jimmy Breck-McKye
0

Jemand muss eine jQuery-Pfadmanager-Schnittstelle für eine Indirektions- und Cache-Ebene zum dom erstellen.

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

Dann,

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

So,

// 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({});
Kennzeichen
quelle