-
Notifications
You must be signed in to change notification settings - Fork 2
/
index.html
238 lines (195 loc) · 10.3 KB
/
index.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description" content="Patterns for vanilla JavaScript UI development.">
<link rel="stylesheet" media="screen" href="style/common.screen.css">
<link rel="stylesheet" media="screen" href="index.screen.css">
<script type="module" src="index.client.js"></script>
<title>Vanilla patterns</title>
</head>
<body>
<div id="content">
<h1>Vanilla patterns</h1>
<div id="content-body">
<aside id="table-of-contents">
<h2>Table of contents</h2>
<ul>
<li><a href="#kiss">KISS—Keep it simple, stupid</a></li>
<li><a href="#list-of-examples">List of examples</a></li>
<li><a href="#how-to-read">How to read the examples</a></li>
<li><a href="#license">License</a></li>
</ul>
</aside>
<p>
This website demonstrates some of the common patterns for developing web applications using vanilla
JavaScript. The term 'vanilla' is used to describe a plain version of something without adornments and
additions. In the context of front end development 'vanilla JavaScript' refers to frameworkless development.
The way 'vanilla' is defined by its practitioners ranges from using abstractions that replace frameworks to a
more strict definition of not using non-application-specific abstractions. This website shows patterns that
are more along the lines of the latter.
</p>
<p>
Specifically this means you will not find replacements for data binding, component libraries, template
engines, and similar. You will instead find various ways to take advantage of features that the browsers
offer, such as the template tag, ES modules, custom elements, constraints validation, form API...
</p>
<p>
If you would like to contribute to this collection or request some pattern, please feel free to file an issue
<a href="https://github.com/foxbunny/vanilla-patterns-2/issues">on GitHub</a>.
</p>
<h2 id="kiss">KISS—Keep it simple, stupid</h2>
<p>
Although this website showcases patterns, it is not intended to be a definitive guide on how to develop with
vanilla JavaScript. The spirit of vanilla JavaScript development is about embracing the available APIs, and
doing the simplest thing that works. Whether some approach described in this website is the simplest or not is
technically not important. Carefully considering options, developing a feel for unnecessary complexity, and
regularly pruning it—these are the guiding principles of the 'vanilla way'.
</p>
<h2 id="list-of-examples">List of examples</h2>
<ul>
<li><a href="using-existing-nodes">Using existing nodes</a></li>
<li><a href="creating-nodes">Creating nodes</a></li>
<li><a href="pre-rendered-list">Pre-rendered list</a></li>
<li><a href="paginated-list">Paginated list</a></li>
<li><a href="sorted-list">Sorted list</a></li>
<li><a href="filtered-list">Filtered list</a></li>
<li><a href="form-validation">Form validation</a></li>
<li><a href="click-outside">Click outside</a></li>
<li><a href="carousel">Carousel</a></li>
<li><a href="drag-order">Drag order</a></li>
<li><a href="button-group">Button group</a></li>
<li><a href="toggle-switch">Toggle switch</a></li>
<li><a href="toasts">Toasts</a></li>
</ul>
<h2 id="how-to-read">How to read the examples</h2>
<p>
Each example consists of three parts: HTML, CSS and JavaScript. These technologies are separate by design, and
as vanillistas, we embrace this separation. Therefore, do not look at just the JavaScript. Look at the HTML
and CSS as well. Some of the examples will use CSS where most developers resort to JavaScript, or rely on and
augment the default HTML behaviors, and this is part of embracing the tools at our disposal.
</p>
<p>
The code base follows certain conventions that are repeated in all examples. To avoid repeatedly explaining
them in each example, I will provide the explanations here:
</p>
<ul>
<li>
<h3>Use the developer tools</h3>
<p>
You will find the developer tools a great help when viewing the examples. Because the code does not
undergo any transformation whatsoever, you will have the complete unadulterated source code available to
you in the dev tools. There is no need to open the code in your editor to see how it's actually written.
</p>
<h3>File names</h3>
<p>
The HTML file's name is used as the base for naming other files.
</p>
<p>
The CSS files use the same base name as the HTML file, and use a <code>.[media].css</code> double
extension. The media is normally "screen" for web applications so for <code>index.html</code>, the CSS
would be named <code>index.screen.css</code>, but a printable web application, we might have an
<code>index.print.css</code>. When linking these files, we use the <code>media</code> attribute on the
<code><link></code> tag, which must match the media in the file extension.
</p>
<p>
JavaScript files normally use a <code>.client.js</code> double extension when there is just one file for
the entire application. This is to differentiate it from a potential <code>.server.js</code> file that we
might have in a full-stack web application. JavaScript are linked to the HTML page using the
standard <code><script></code> tag, either using a <code>defer</code> attribute (without a value)
or <code>type="module"</code>.
</p>
</li>
<li>
<h3>Placement of the <code><script></code> tags</h3>
<p>
The <code><script></code> tags is placed in the <code><head></code> tag, not the bottom of the
<code><body></code>. When using the <code>defer</code> or <code>type="module"</code> attribute, the
JavaScript files are downloaded in parallel with parsing of the HTML. Therefore, we want to allow the
browser to find them as soon as possible. The scripts are not executed until the document is parsed and
DOM tree populated, so there is no need to place the scripts below page content.
</p>
<p>
When using a build tool to bundle our sources, we should ensure that the tool outputs the
<code><script></code> as described here.
</p>
</li>
<li>
<h3>Use of ES modules</h3>
<p>
Since ES modules are supported in all major browsers, we use them for all JavaScript code. We do this even
in cases where we are not importing or exporting any module members because a module also prevents
variables from the module from becoming global.
</p>
<p>
An alternative to our use of modules would be to use the <code>defer</code> attribute on the
<code><script></code> tag, but then wrap the entire contents of the script file in a block:
</p>
<pre><code>{
let someVariable = 'not going to leak into global scope'
}</code></pre>
<p>
Here, we do not use the second method because it causes the code within the block to be indented in most
editors, and those leading tabs/spaces increase the payload.
</p>
</li>
<li>
<h3>Variables starting with the <code>$</code> character</h3>
<p>
Some variables start with the dollar (<code>$</code>) character. These are variables that contain
references to DOM nodes. Sometimes, a variable may be just a single dollar character, and that an
"anonymous" node, usually used when iterating over a collection of nodes.
</p>
<p>
Some variables start with two dollar characters (<code>$$</code>). This is not a reference to
<a href="https://en.wikipedia.org/wiki/Vash_the_Stampede">Vash the Stampede</a>. We use this convention to
denote variables that contain references to collections or arrays of DOM nodes.
</p>
</li>
<li>
<h3>Mismatch between the <code>id</code> attribute and variable name</h3>
<p>
In most cases, there is a mismatch between what the variable is named in the HTML (its <code>id</code>
attribute) and how it is referred to in the code. For instance, an element on the page may have an
<code>id="clock"</code>, but the variable name may be <code>$output</code>. We do this because HTML
<code>id</code> attribute describes what the element is in the content structure, while the JavaScript
variable name describes its role in the code. In JavaScript, the clock is an output of the code that
calculates and formats the current time. This is a form of loose coupling: changing the role of the
element on the page does not require us to update the variable name, and vice versa.
</p>
</li>
<li>
<h3>Indent with tabs</h3>
<p>
Indenting with spaces uses more characters for indentation than tabs. Since we are not using any build
tools, using tabs for indentation saves us characters.
</p>
</li>
<li>
<h3>Entry point at the top</h3>
<p>
In all examples, the entry point–the function which sets up the application–is called <code>start()</code>,
and it is placed at the top. It is invoked as a <code>requestIdleCallback()</code> callback.
</p>
<p>
Entry point is placed at the top of the file because it makes it easier for us to orient ourselves when we
first visit the code base. The entry point is followed by variables holding references to DOM nodes, and
then by other functions ordered by distance from the entry point–those directly used in the entry point
are closer to the entry point. We do not follow this rule literally, however. It's mostly about balance.
If two functions are strongly related, they should be closer to each other.
</p>
</li>
</ul>
<h2 id="license">License</h2>
<p>
This code is released under the terms of the WTFPL2 license. See the <a href="LICENSE">LICENSE</a> file for
details. You are free to copy any portion of the code and modify it as you wish for any purpose.
</p>
<p>
<small>Copyright© 2023. Hajime Yamasaki Vukelic. Some rights reserved.</small>
</p>
</div>
</div>
</body>
</html>