Ich hatte neulich einen Mann, der mir geschrieben hat. Er hatte etwas HTML, CSS und JavaScript, und es verhielt sich einfach nicht so, wie er es erwartet hätte. Das HTML enthielt einige Platzhalter und das JavaScript enthielt einige Daten, und die Annahme war, dass die Daten die Platzhalter füllen würden.
Für diejenigen von uns mit einem gewissen Webwissen können wir uns das ansehen und verstehen, warum es nicht so funktioniert, wie er es sich vorgestellt hat. Aber ich denke, es ist auch wertvoll, die Dinge aus dieser Perspektive zu betrachten und dann nach Lösungen zu suchen, die hoffentlich so einfach sind, wie das ursprüngliche Problem zu sein scheint.
Der HTML-Code sah ungefähr so aus…
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Test</title>
<link rel="stylesheet" href="test.css">
<script src="data.js"></script>
</head>
<body>
<section>
<div>{company_name}</div>
</section>
</body>
</html>
Der JavaScript-Code sah ungefähr so aus…
var company_data = {
"{company_name}" : "SOME COMPANY",
};
Hier passiert nichts Ungültiges.
Das ist alles vollkommen gültiger Code. Er ist richtig verknüpft. Er wird ausgeführt. Er tut nichts anderes, als {company_name} auf dem Bildschirm anzuzeigen. Die Erwartung war, dass stattdessen SOME COMPANY auf dem Bildschirm angezeigt wird, wobei der Platzhalter {company_name} durch die Daten aus der JavaScript-Datei ersetzt wird.
Lassen Sie uns das mit einer Einzeiler-Lösung beheben.
In diesem genauen Szenario müssen wir, um den richtigen Firmennamen anzuzeigen, dieses Element im DOM auswählen und seinen Inhalt durch unsere Daten ersetzen. Wir könnten das tun, indem wir diese eine zusätzliche Zeile zu JavaScript hinzufügen
var company_data = {
"{company_name}": "SOME COMPANY"
};
document.querySelector("div").innerHTML = company_data["{company_name}"];
Das ist nicht besonders wiederverwendbar oder robust, aber hey, es ist auch kein Overthinking oder Overtooling.
Die Erwartung war Templating
Ich denke, wir können zu diesem Zeitpunkt erkennen, dass das, was er hoffte, passieren würde, dass diese Art von Templating automatisch stattfinden würde. Bereitstellen eines Objekts mit Schlüsseln, die mit denen im HTML übereinstimmen, und der Inhalt in diesem HTML wird automatisch ausgetauscht. Mit reinen Webtechnologien funktioniert das einfach nicht so.
Kein Witz, es gibt Hunderte von Möglichkeiten, dies zu handhaben. Hier sind ein paar, die mir spontan einfallen:
- Verwenden Sie eine Templating-Sprache wie Handlebars oder Mustache
- Verwenden Sie einen statischen Website-Generator wie Eleventy, der standardmäßig Liquid verwendet
- Erstellen Sie ein HTML-
<template>-Element und schreiben Sie Ihr eigenes Skript, um es zu verwenden - Erstellen Sie eine Web Component
- Verwenden Sie stattdessen eine Backend-Sprache oder eine Sprache wie Nunjucks, um die Verarbeitung im Voraus durchzuführen
- Verwenden Sie einen Präprozessor wie Pug
Als allgemeine Präferenz würde ich sagen, dass es am besten ist, das Templating serverseitig oder während eines Builds durchzuführen – warum das DOM manipulieren, wenn es nicht nötig ist?
Aber um diesen Rat für eine Sekunde zu ignorieren, hier ist ein Beispiel, wie man es clientseitig mit Handlebars macht, nur damit der Mann aus der ursprünglichen E-Mail ein funktionierendes Beispiel hat, wie das funktionieren kann
Wäre die einfachste Lösung nicht, eine (eindeutige) ID zu haben, wie
Dann nach der ID suchen und die innerHTML mit dem Inhalt in JavaScript füllen?
Ich denke, dies ist ein aufkommendes Problem in der Komplexität von Webtechnologien. Es ist unwahrscheinlich, dass ein Neuling mit den grundlegenden Bausteinen in der gleichen Reihenfolge beginnt, wie es ein alter Hase (wie Sie oder ich) tun würde; HTML, dann CSS, dann JavaScript, dann JS-Snippets, Frameworks usw.
Da die Wissensfläche im Internet so unglaublich riesig ist, kann der erste Eindruck eines Neulings React / Vue / svelte / irgendetwas sein. Das Templating-Problem ist ein großartiges Beispiel für Realität vs. Erwartung.
@David King: Danke für Ihren Kommentar. Ihre Ausführungen fassen den Kernpunkt präzise und prägnant zusammen, was ich bewundere.
Zwei Gedanken
1. Ist „aufkommend“ zutreffend?
2. Beschränkt sich dieses Problem auf die Komplexität von „Webtechnologien“?
Wenn ich über meine eigene Erfahrung nachdenke, denke ich, dass die Einstiegshürde jetzt quantensprungartig niedriger ist und die Möglichkeiten, Dinge in der richtigen Reihenfolge zu lernen, immer noch reichlich vorhanden sind (z. B. HTML Goodies, MDN, You Don’t Know JS).
Dies war ein Problem für mich, als ich vor 23 Jahren anfing, aber es gab kein Google, YouTube, StackOverflow, Quota usw. voller Leute, die erklärten, wie man vorgeht.
Auch das Skript data.js muss sich direkt über dem Tag befinden, sonst
document.querySelector("div")gibt null zurück, weil das Element zu diesem Zeitpunkt nicht existiert.
Habe noch nie von eleventy oder dem html template Tag gehört. Danke für den Tipp, ich werde mich damit beschäftigen :)
direkt über dem
</body>-Tag *Schön und informativ, danke für das Teilen.
Auf die Gefahr hin, den Sinn zu verfehlen (zweifellos war der ursprüngliche Anwendungsfall komplizierter als das, was gezeigt wurde), denke ich, dass es fair ist zu sagen, dass es manchmal in Ordnung ist, einfach nur HTML zu schreiben
Ich würde sagen,
.textContentwäre aus Sicherheits- und Performancegründen eine bessere Option als.innerHTML.Irgendwie haben Sie es für jeden Anfänger schwerer gemacht, indem Sie abstraktere Namen in Handlebars (wie
source,context, sogartemplateoderhtml– oder ähnliches) verwendet haben, ganz zu schweigen davon, dass Sie sie mit „const“ anstelle von „var“ behandelt haben :)Vielleicht habe nur ich ein Problem mit der Namenskonvention, aber das kann die Lernkurve für einen reinen Anfänger wirklich brechen.
Lassen Sie mich Ihnen erklären, warum
– Erstens wäre eine gute Lösung, tatsächlich einen Einzeiler zu verwenden, aber etwas viel Einfacheres und Intuitiveres, wie z. B. jQuery, etwas, um den Neulingen langsam das Konzept von Getter und Setter näherzubringen [den Wert holen und dann die Anzeige der Daten setzen]. Angesichts dessen ist es offensichtlich, dass die tatsächlich als
sourcebezeichnete Sache NICHT das innerHTML ist – da diese Sache tatsächlich das Ziel der Daten ist und nicht ihrUrsprung. Das innerHTML wartetdurstigauf Daten, auch aus verschiedenen Quellen, wenn möglich, also ist es ziemlich ein Konsument von Daten, der Ort, an dem alles endet.Dieser jQuery-Einzeiler könnte sein
viel intuitiver als die Verwendung des hässlichen camelCase-Namens querySelector (wieder eine schreckliche Namenswahl für etwas, das eigentlich keine
Abfrage auswählt, sondern ein Element, richtig?…)Ich erspare Ihnen hier allen, die jQuery-Zeile aufzuschreiben, weil es hier nicht um das Schreiben von Code geht, sondern um Einfachheit beim Entwurf des Programmieransatzes – auch weil die Leser hier viel weiter sind als die Noobs.
– Einst sagten die Beatles den Leuten: Alles, was wir brauchen, ist Liebe. Im Coding brauchen wir nur gute Namen – um eine Sprache zugänglicher und lesbarer zu machen. Ich schaue mir die Lektion an, die uns der bescheidenste (und nicht einmal eine Programmiersprache an sich) erteilt hat, nämlich das reine HTML :) Trotz der Tatsache, dass es nicht mit solchen Komplexitäten wie JavaScript umgeht, kam es auf die geniale Idee, Dinge
semantischzu machen, um alle vor schlechten Idiomen zu retten. Können wir in diesem Fall Semantik verwenden? Ja, das können wir.– Eine weitere schreckliche Namensgebung ist die Verwendung von
templatefür etwas, das von einer Methode kommt – eine Methode ist selbst eine Funktion – und es in einem Container – einer Variable – zu speichern. Wieder vielleicht zu viel für den Geschmack eines Anfängers :)Zu sagen „const template =…“ bereitet den Leser irgendwie darauf vor, sorgfältig nach einem bestimmten Muster zu suchen, oder? Weil Template schließlich wie ein Muster ist, das eine präzise Form oder ein Gewebe irgendeiner Art hat! Und stattdessen sehen sie dort ein Nichts, nur ein leeres Wort, eigentlich eine Art Referenz (etwas kompilieren, ok?) was bedeutet „geh irgendwohin und verarbeite etwas“, also (scherzhaft) vielleicht verstehst du unterwegs, was dort passiert. Wie zu sagen:
Der Geschmack von Kuchen kennt man erst, wenn man ihn isst:D … Kein echtes Template da, nichts, nur ein Aufruf zum Handeln (ein Buzz oder Barr kompilieren)…Soll ich weitermachen? Das Wort
contextwird hier wieder missbraucht. Ich würde es besseroriginnennen, weil es sich nur auf eine bloße Datensammlung bezieht, nichts viel Wichtigeres. Origin bedeutet auch etwas Frisches und Nützliches – wie die Daten, die wir aus verschiedenen Quellen (Backend, eine API, Sie nennen es) verwenden könnten. Im Gegenteil, eincontextist normalerweise der Raum, in demDinge passieren, die fröhliche Nachbarschaft, in der dieKind-Daten zu Erwachsenen und Endnutzung heranwachsen – also sind es NICHT die Daten selbst :(.Die letzte Zeile verschlimmert alles: Anstatt es
resultzu nennen, heißt eshtml. Und die schrecklichen Dinge passieren weiter (der Noob sieht wieder entsetzt, dass die Sache namenstemplateeine Funktion ist, keine Variable – und nicht einmal eine Variable, da sie in der vorherigen Zeile als „const“ bezeichnet wird…)Versteifen Sie mich nicht, ich liebe, was Handlebars tut, aber ich war von Anfang an gegen ihre idiotische Art, Dinge zu benennen, als ich in Postman sah, wie sie dort wirklich regierten :D
Ändern Sie die N-A-M-E-N, und ja, Sie werden die wahre Schönheit & Kraft von cOdE sehen. KISS :) (Keep it simple, stupid) – für Noobs, oder YAGNI für extreme Performance-Programmierer ;)
Danke.
PS Ich schreibe diesen Kommentar auf meinem Handy, es war eine Belastung für mich, den obigen JS-Code mit meinen eigenen Namensvorschlägen neu zu schreiben, also bitte jeder, der es auf seinem eigenen Computer für Sie tut. Definitiv würde es besser schmecken. :) Ich wünsche / hoffe / dieses Thema würde eine gesunde Debatte über den wahren Kern des Programmierens auslösen. Nochmals vielen Dank an den Gastgeber der Diskussion! Ich schätze Ihre Arbeit
Was Michael Jackson entdeckte, als er an Mustache arbeitete, war, dass Templates immer versuchen, JavaScript neu zu erfinden und Ihre Benutzer zu zwingen, eine neue Syntax zu lernen. https://twitter.com/mjackson/status/803808828634472448
JSX ist großartig, weil es Ihnen erlaubt, eine Template-ähnliche Syntax mit JavaScript zu schreiben, aber das Hauptproblem dabei ist, dass es Sie zwingt, viele unbeholfene Muster wie Short-Circuiting zu verwenden.
Ich persönlich denke, es wäre ideal, wenn es eher wie PHP-Templates funktionieren würde, wo Sie Ihren Logikcode in nativem JS schreiben und HTML dazwischen einfügen können. Keine Frameworks, nur JavaScript und HTML.
Alpine.js ist ziemlich raffiniert. Es ist Inline-JavaScript und die Syntax ist an Vue.js angelehnt, aber ohne Shadow DOM. Templating wäre damit ziemlich einfach
Gute Empfehlung, das Templating wenn möglich serverseitig durchzuführen. In diesem Szenario können Sie Hypertag (http://hypertag.io/) ausprobieren, eine von Python inspirierte Sprache zur Dokumentengenerierung, mit sauberer einrückungsbasierter Syntax und vielen fortgeschrittenen Funktionen: native benutzerdefinierte Tags, DOM-Manipulation, zusammengesetzte Ausdrücke… Schnelleinstieg: https://github.com/mwojnars/hypertag