Heim > Artikel > Web-Frontend > Entkoppeln Sie HTML, CSS und JS
Im Internet enthält derzeit jede etwas komplexe Website oder Anwendung viel HTML, CSS und JavaScript. Da sich die Nutzung des Internets weiterentwickelt und unsere Abhängigkeit davon zunimmt, ist ein Plan zur Organisation und Pflege Ihres Front-End-Codes ein absolutes Muss.
Einige der heutigen großen Internetunternehmen werden versuchen, die Modularität des Codes beizubehalten, da immer mehr Menschen einer zunehmenden Anzahl von Front-End-Codes ausgesetzt sein werden. Wenn Sie einen Teil des Programmcodes auf diese Weise ändern, wird die Ausführung nachfolgender, nicht zusammenhängender Teile nicht unbeabsichtigt zu stark beeinträchtigt.
Unbeabsichtigte Folgen zu verhindern ist kein leicht zu lösendes Problem, insbesondere da HTML, CSS und JavaScript von Natur aus voneinander abhängig sind. Erschwerend kommt hinzu, dass beim Front-End-Code einige traditionelle Prinzipien der Informatik, wie z. B. die Trennung von Belangen, die seit langem in der serverseitigen Entwicklung verwendet wird, selten diskutiert werden.
In diesem Artikel werde ich darüber sprechen, was ich über die Entkopplung meines HTML-, CSS- und JavaScript-Codes gelernt habe. Aus persönlicher Erfahrung und der Erfahrung anderer ist der beste Weg, dies zu erreichen, nicht offensichtlich, oft nicht intuitiv und widerspricht manchmal vielen sogenannten Best Practices.
Ziel
Es wird immer eine Kopplung zwischen HTML, CSS und JavaScript geben. Unabhängig davon sind diese Technologien von Natur aus darauf ausgelegt, miteinander zu interagieren. Beispielsweise kann ein Flash-Übergangseffekt in einem Stylesheet mit einem Klassenselektor definiert werden, er wird jedoch häufig durch HTML initialisiert und durch Benutzerinteraktion, beispielsweise das Schreiben von JavaScript, ausgelöst. Da eine gewisse Kopplung von Front-End-Code unvermeidbar ist, sollte Ihr Ziel nicht darin bestehen, die Kopplung einfach zu beseitigen, sondern unnötige Abhängigkeitskopplungen zwischen Codes zu reduzieren. Ein Backend-Entwickler sollte in der Lage sein, Änderungen am Markup in HTML-Vorlagen vorzunehmen, ohne befürchten zu müssen, versehentlich gegen CSS-Regeln oder einige JavaScript-Funktionen zu verstoßen. Da die heutigen Webteams immer größer und spezialisierter werden, ist dieses Ziel wichtiger denn je.
Anti-Pattern
Eine enge Kopplung im Front-End-Code ist nicht immer offensichtlich. Tatsächlich besteht die Komplexität darin, dass das, was auf der einen Seite als lose Kopplung erscheint, auf der anderen Seite eng gekoppelt ist. Hier sind alle Anti-Patterns, die ich schon oft gemacht oder gesehen habe und aus meinen Fehlern gelernt habe. Für jedes Muster versuche ich zu erklären, warum die Kopplung so schlecht ist, und zeige auf, wie man sie vermeiden kann.
Überkomplexe Selektoren
CSS Zen Garden hat der Welt gezeigt, dass Sie das Aussehen einer gesamten Website vollständig ändern können, ohne ein einziges HTML-Tag zu ändern. Dies ist typisch für die Semantic-Web-Bewegung, bei der eines der Hauptprinzipien darin besteht, die Verwendung von Präsentationsklassen zu vermeiden. Auf den ersten Blick scheint CSS Zen Garden ein gutes Beispiel für die Entkopplung zu sein; schließlich geht es ihm darum, den Stil von der Markup-Sprache zu trennen. Wenn Sie dies tun, tritt jedoch häufig das Problem auf, dass Sie einen solchen Selektor in Ihrem Stylesheet haben müssen:
#sidebar section:first-child h3 + p { }
CSS Zen Garden, obwohl HTML fast vollständig identisch mit CSS Separation ist , aber CSS wird stark an HTML gekoppelt sein, was ein tiefes Verständnis der Struktur der Auszeichnungssprache erfordert. Dies scheint keine schlechte Sache zu sein, insbesondere wenn jemand das CSS pflegt und auch den HTML-Code pflegen muss, aber sobald Sie viele Leute hinzufügen, wird die Situation unüberschaubar. Wenn ein Entwickler unter bestimmten Umständen ein dc6dce4a544fdca2df29d5ac0ea9906b hinzufügt, wird die obige Regel nicht wirksam, aber er weiß nicht, warum.
Solange sich das Markup Ihrer Website selten ändert, ist CSS Zen Garden eine sehr gute Idee. Dies ist jedoch bei heutigen Webanwendungen nicht unbedingt der Fall. Im Vergleich zu langen und komplizierten CSS-Selektoren besteht die beste Möglichkeit darin, einen oder mehrere Klassenselektoren zum Stammelement der visuellen Komponente selbst hinzuzufügen. Wenn die Seitenleiste beispielsweise Untermenüs hat, müssen Sie nur einen Untermenü-Klassenselektor für jedes Untermenüelement hinzufügen, anstatt dieses Formular zu verwenden:
ul.sidebar > li > ul { /* submenu styles */ }
Das Ergebnis dieses Ansatzes ist, dass mehr Code in der benötigt wird HTML-Klassenselektoren, aber auf lange Sicht reduziert dies die Kopplung, macht den Code wiederverwendbar und wartbar und macht Ihr Markup selbstdokumentierend. Ohne Klassenselektoren in HTML wüssten Entwickler, die mit CSS nicht vertraut sind, nicht, wie sich Änderungen an HTML auf anderen Code auswirken. Andererseits macht die Verwendung von Klassenselektoren in HTML sehr deutlich, welche Stile oder Funktionen verwendet werden.
Die Verantwortlichkeiten mehrerer Klassenselektoren
Ein Klassenselektor wird häufig sowohl als Stil als auch als JavaScript-Hook verwendet. Obwohl dies wirtschaftlich erscheinen mag (da mindestens ein Klassen-Tag reduziert wird), koppelt es tatsächlich die Leistung und Funktionalität des Elements.
<button class="add-item">Add to Cart</button>
Das obige Beispiel beschreibt eine Schaltfläche „In den Warenkorb“ mit dem Klassenstil „Artikel hinzufügen“.
如果开发者想为此元素添加一个单击事件监听器,用已经存在的类选择器作为钩子非常的容易。我的意思是,既然已经存在了一个,为何要添加另一个呢? 但是想想看,有很多像这样的按钮,遍布了整个网站,都调用了相同的JavaScript功能。再想想看,如果市场团队想要其中一个和其它看起来完全不同但功能相同的按钮呢。也许这样就需要更多显著的色彩了。
问题就来了,因为监听单击事件的JavaScript代码希望add-item类选择器被使用到,但是你新的按钮又无法使用这个样式(或者它必须清除所有声明的,然后再重置新的样式)。还有,如果你测试的代码同时也希望使用add-item类选择器,那么你不得不要去更新那么代码用到的地方。更糟糕的是,如果这个”添加到购物车”功能不仅仅是当前应用用到的话,也就是说,把这份代码抽象出来作为一个独立的模块,那么即使一个简单的样式修改,可能会在完全不同的应用中引发问题。
使用javaScript钩子最好的(事实上也是比较鼓励的)做法是,如果你需要这么做,使用一种方式来避免样式和行为类选择器之间的耦合。
我的个人建议是让JavaScript钩子使用前缀,比如:js-*。这样的话,当开发者在HTML源代码中看到这样的类选择器,他就完全明白个中原因了。所以,上述的”添加到购物车”的例子可以重写成这样:
<button class="js-add-to-cart add-item">Add to Cart</button>
现在,如果需要一个看起来不同的按钮,你可以很简单地修改下样式类选择器,而不管行为的类选择器。
<button class="js-add-to-cart add-item-special">Add to Cart</button>
JavaScript更多的样式操作
JavaScript能用类选择器去DOM中查找元素,同样,它也能通过增加或移除类选择器来改变元素的样式。但如果这些类选择器和当初加载页面时不同的话也会有问题。当JavaScript代码使用太多的组成样式操作时,那些CSS开发者就会轻易去改变样式表,却不知道破坏了关键功能。也并不是说,JavaScript不应该在用户交互之后改变可视化组件的外观,而是如果这么做,就应该使用一种一致的接口,应该使用和默认样式不一致的类选择器。
和js-*前缀的类选择器类似,我推荐使用is-*前缀的类选择器来定义那些要改变可视化组件的状态,这样的CSS规则可以像这样:
.pop-up.is-visible { }
注意到状态类选择器(is-visible)是连接在组件类选择器(pop-up)后,这很重要。因为状态规则是描述一个的状态,不应该单独列出。如此不同就可以用来区分更多和默认组件样式不同的状态样式。
另外,可以让我们可以编写测试场景来保证像is-*这样的前缀约定是否遵从。一种测试这些规则的方式是使用CSSLint和HTML Inspector。
更多关于特定状态类选择可以查阅Jonathan Snnok编写的非常优秀的SMACSS书籍。
JavaScript”选择器”
jQuery和新的API,像document.querySelectorAll,让用户非常简单地通过一种他们已经非常熟悉的语言–CSS选择器来查找DOM中的元素。虽然如此强大,但同样有CSS选择器已经存在的相同的问题。JavaScript选择器不应过度依赖于DOM结构。这样的选择器非常慢,并且需要更深入认识HTML知识。
就第一个例子来讲,负责HTML模板的开发者应该能在标记上做基本的改动,而不需担心破坏基本的功能。如果有个功能会被破坏,那么它就应该在标记上显而易见。
我已经提及到应该用js-*前缀的类选择器来表示JavaScript钩子。另外针对消除样式和功能类选择器之间的二义性,需要在标记中表达出来。当某人编写HTML看到js-*前缀的类选择器时,他就会明白这是别有用途的。但如果JavaScript代码使用特定的标记结构查找元素时,正在触发的功能在标记上就不那么明显了。
为了避免使用冗长而又复杂的选择器遍历DOM,坚持使用单一的类或者ID选择器。 考虑以下代码:
var saveBtn = document.querySelector("#modal div:last-child > button:last-child")
这么长的选择器是可以节省你在HTML中添加一个类选择器,但同样让你的代码对于标记更改非常容易受到影响。如果设计者突然决定要把保持按钮放在左边,而让取消按钮放在右边,这样的选择器就不再匹配了。
一个更好的方式(使用上述的前缀方法)是仅仅使用类选择器。
var saveBtn = document.querySelector(".js-save-btn")
现在标记可以更改它想改的,并且只要类选择还是在正确的元素上,一切都会很正常。
类选择器就是你的契约
Durch die Verwendung geeigneter Klassenselektoren und vorhersehbarer Klassennamenkonventionen kann die Kopplung zwischen fast allen Arten von HTML, CSS und JavaScript verringert werden. Auf den ersten Blick scheint die Verwendung vieler Klassenselektoren im Markup ein Zeichen einer starken Kopplung zu sein, da Sie die Namen vieler Klassenselektoren kennen müssen, um den HTML-Code darzustellen. Aber ich finde, dass die Verwendung von Klassenselektoren dem Ereignis- oder Beobachtermuster im traditionellen Programmierdesign sehr ähnlich ist. Bei der ereignisgesteuerten Programmierung ruft Objekt B Objekt B nicht direkt auf Objekt A auf, sondern veröffentlicht einfach ein bestimmtes Ereignis in der bereitgestellten Umgebung, und Objekt B kann dieses Ereignis dann abonnieren. Auf diese Weise muss Objekt B nichts über die Schnittstelle von Objekt A wissen, sondern nur wissen, auf welche Ereignisse es warten muss. Es liegt auf der Hand, dass das Ereignissystem irgendeine Form der Kopplung erfordert, da Objekt B den Ereignisnamen kennen muss, den es abonnieren möchte. Im Vergleich zu Objekt A, das die öffentlichen Methoden von Objekt B kennen muss, handelt es sich jedoch bereits um eine lockerere Kopplung.
HTML-Klassenselektoren sind alle sehr ähnlich. Im Gegensatz zur Definition komplexer Selektoren in CSS-Dateien (genau wie bei der internen Schnittstelle von HTML) ist es möglich, das Erscheinungsbild einer visuellen Komponente einfach über einen einzelnen Klassenselektor zu definieren. Der CSS-Datei muss es egal sein, ob der HTML-Code Klassenselektoren verwendet oder nicht. Ebenso verwendet JavaScript keine komplexen DOM-Traversal-Funktionen, die ein tieferes Verständnis der HTML-Struktur erfordern, sondern wartet einfach auf Benutzerinteraktionen an Elementen mit demselben Klassennamen. Klassenselektoren sollten wie der Klebstoff sein, der HTML, CSS und JavaScript zusammenhält. Aus eigener Erfahrung weiß ich, dass sie auch die einfachste und beste Möglichkeit sind, die drei Technologien zu verbinden, ohne sie zu stark zu vermischen.
Zukunft
Die Web Hypertext Technology Working Group (WHATWG) arbeitet an einer Spezifikation für Webkomponenten, die es Entwicklern ermöglichen wird, HTML, CSS und JavaScript zu binden Wird zusammen als separate Komponente oder Modul definiert und interagiert mit anderen Seitenelementen, um es zu kapseln. Wenn diese Spezifikation in den meisten Browsern implementiert wäre, würden viele der Vorschläge, die ich in diesem Artikel mache, an Bedeutung verlieren (weil klar wäre, mit wem der Code interagiert). Sie werden gebraucht und bleiben wichtig. Auch wenn diese Praktiken im Zeitalter der Webkomponenten an Bedeutung verlieren werden, gilt die Theorie immer noch. Die in großen Teams und großen Anwendungen verwendeten Vorgehensweisen gelten weiterhin für das Schreiben kleiner Module, jedoch nicht umgekehrt.
Fazit
Das Markenzeichen von wartbarem HTML, CSS und JavaScript ist, dass jeder Entwickler jeden Teil der Codebasis einfach und sicher schreiben kann, ohne sich darüber Sorgen machen zu müssen Diese Änderungen wirken sich unbeabsichtigt auf andere, nicht verwandte Teile aus. Eine der besten Möglichkeiten, unbeabsichtigte Konsequenzen wie diese zu verhindern, besteht darin, ihm einen vorhersehbaren, menschenähnlichen Satz von Klassenselektornamen zu geben, die seine Bedeutung vermitteln und von jedem Entwickler verwendet werden können, der darauf stößt. Die drei Technologien werden miteinander kombiniert.
Um die oben genannten Anti-Patterns zu vermeiden, beachten Sie bitte die folgenden Grundsätze:
1. Geben Sie in CSS und JavaScript expliziten Komponenten- und Verhaltensklassenselektoren und nicht komplexen CSS-Selektoren Vorrang .
2. Benennen Sie Komponenten basierend auf dem, was sie sind, nicht darauf, wo sie sich befinden.
3. Verwenden Sie nicht denselben Klassenselektor für Stil und Verhalten.
4 zwischen Zustandsstil und Standardstil
Die Verwendung von Klassenselektoren in HTML erfordert oft die Anzeige vieler Klassenselektoren, aber was Sie gewinnen, ist Vorhersehbarkeit und Wartbarkeit, was Anerkennung verdient. Schließlich ist das Hinzufügen von Klassenselektoren zu HTML recht einfach und erfordert vom Entwickler nur geringe Fähigkeiten. Auszug aus den Originalworten von Nicolas Gallagher:
Wenn Sie nach einer Möglichkeit suchen, den Zeitaufwand für das Schreiben und Ändern von CSS zu reduzieren, um HTML und CSS zu erstellen, ist dies genau das Richtige für Sie beinhaltet Sie müssen akzeptieren, dass Sie, wenn Sie den Stil ändern möchten, nicht mehr Zeit damit verbringen möchten, den Klassenselektor für das HTML-Element zu ändern. Dies ist sowohl für Front-End- als auch für Back-End-Entwickler von Nutzen, und jeder kann vorgefertigte LEGO-Steine neu anordnen. Dann wird niemand mit der Magie von CSS prahlen.
Weitere Artikel zum Thema Entkopplung von HTML, CSS und JS finden Sie auf der chinesischen PHP-Website!