Compare commits

...

1 Commits

9 changed files with 234 additions and 205 deletions
Split View
  1. +7
    -0
      .bin/export.sh
  2. +8
    -5
      README.md
  3. +6
    -1
      app.js
  4. +20
    -0
      package-lock.json
  5. +23
    -21
      package.json
  6. +87
    -109
      posts/basic-http-routing-in-golang.html
  7. +0
    -0
      posts/project-led.html
  8. +9
    -0
      posts/project-led.json
  9. +74
    -69
      posts/vanilla-js-basics.html

+ 7
- 0
.bin/export.sh View File

@ -0,0 +1,7 @@
#!/bin/bash
for filename in posts/*.md; do
NEWFILENAME="$(basename "$filename" .md).html"
./node_modules/.bin/md2html $filename > "posts/$NEWFILENAME"
done

+ 8
- 5
README.md View File

@ -9,7 +9,7 @@ _This file is intended to help you remember the thing you made way back then..._
## Instructions
1. Create your html file and put it in `/posts`
1. Create your Markdown file and put it in `/posts`
2. Then create the meta file for it of the same name but using the ext `.json`. This file should look like:
{
@ -23,13 +23,16 @@ _This file is intended to help you remember the thing you made way back then..._
"categories" : ["misc", "programming", "js", "etc..."]
}
3. Commit, Push and Pull.
3. To create the HTML file run:
npm run export
3. Test, Commit, and Push.
## Pull from Digital Ocean
1. SSH into server `ssh root@45.55.44.195`
2. Enter correct dir `cd /home/forge/leviolson-website`
1. SSH into server `ssh root@206.189.236.142`
2. Enter correct dir `cd /opt/apps/leviolson.com`
3. Pull in changes `git pull && npm i`
4. Restart the service `pm2 restart LeviOlson.com`
5. Verify it restarted correctly `pm2 logs LeviOlson.com`

+ 6
- 1
app.js View File

@ -8,6 +8,11 @@ const app = express()
app.use(express.static('public'))
const env = process.env.NODE_ENV
if (env === 'dev') {
app.use('/coverage', express.static('coverage'))
}
app.set('view engine', 'ejs')
app.get('/', (req, res) => {
@ -93,4 +98,4 @@ app.get('/posts/:post', (req, res) => {
const port = 3000
app.listen(port, () => console.log('Example app listening on port ' + port + '!'))
module.exports = app
module.exports = app

+ 20
- 0
package-lock.json View File

@ -1871,6 +1871,26 @@
"object-visit": "^1.0.0"
}
},
"markdown": {
"version": "0.5.0",
"resolved": "https://registry.npmjs.org/markdown/-/markdown-0.5.0.tgz",
"integrity": "sha1-KCBbVlqK51kt4gdGPWY33BgnIrI=",
"dev": true,
"requires": {
"nopt": "~2.1.1"
},
"dependencies": {
"nopt": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/nopt/-/nopt-2.1.2.tgz",
"integrity": "sha1-bMzZd7gBMqB3MdbozljCyDA8+a8=",
"dev": true,
"requires": {
"abbrev": "1"
}
}
}
},
"media-typer": {
"version": "0.3.0",
"resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",

+ 23
- 21
package.json View File

@ -1,23 +1,25 @@
{
"name": "website",
"version": "1.0.0",
"description": "Levi's Website",
"main": "app.js",
"dependencies": {
"ejs": "^2.5.9",
"express": "^4.16.3"
},
"devDependencies": {
"chai": "^4.1.2",
"nodemon": "^1.18.10",
"supertest": "^3.0.0"
},
"scripts": {
"start": "node app.js",
"startdev": "./node_modules/.bin/nodemon app.js",
"test": "nyc --reporter=html --reporter=text mocha --timeout 10000 --colors --exit",
"coverage": "nyc --reporter=html --reporter=text mocha --timeout 10000 --exit"
},
"author": "Levi Olson <me@leviolson.com>",
"license": "UNLICENSE"
"name": "website",
"version": "1.0.0",
"description": "Levi's Website",
"main": "app.js",
"dependencies": {
"ejs": "^2.5.9",
"express": "^4.16.3"
},
"devDependencies": {
"chai": "^4.1.2",
"markdown": "^0.5.0",
"nodemon": "^1.18.10",
"supertest": "^3.0.0"
},
"scripts": {
"start": "node app.js",
"startdev": "NODE_ENV=dev ./node_modules/.bin/nodemon app.js",
"test": "nyc --reporter=html --reporter=text mocha --timeout 10000 --colors --exit",
"coverage": "nyc --reporter=html --reporter=text mocha --timeout 10000 --exit",
"export": ".bin/export.sh"
},
"author": "Levi Olson <me@leviolson.com>",
"license": "UNLICENSE"
}

+ 87
- 109
posts/basic-http-routing-in-golang.html View File

@ -1,30 +1,28 @@
<h1 id="basic-http-routing-in-golang">Basic HTTP Routing in Golang</h1>
<p>Golang is incredibly powerful. Its standard library has so much to offer, but I think other languages have encouraged the
use of external libraries for even the most basic tasks. For example, with JavaScript, most inexperienced developers
seem to use jQuery to do simple tasks like selecting an element and replacing its contents. When you and I both know
jQuery is way overkill for such a task.
<a href="https://leviolson.com/posts/vanilla-js-basics">See my article on Vanilla JS basics</a>.</p>
<p>I believe that in order to be considered an expert in a language, you must at least be able to demonstrate using the core
language to achieve your goal. In our current case, HTTP routing. Now to be clear, I don't think you need to write everything
from scratch all the time, but you should have a firm grasp on what is available by the core language, and when you are
better suited to use an external library. If you are looking for more advanced HTTP routing, then I would suggest using
something like
<a href="https://github.com/gin-gonic/gin">gin</a>.</p>
<p>Enough ranting, let's get to it.</p>
<h2 id="assumptions">Assumptions</h2>
<p>I assume you have basic knowledge of the Go language at this point, so if not, it might be worth searching for some entry
level basics first. See
<a href="https://tour.golang.org">A Tour of Go</a>.</p>
<h2 id="lets-begin">Let's begin</h2>
<p>The accompanying repo for the code produced in this article is located
<a href="https://github.com/leothelocust/basic-http-routing-in-golang">on github</a>.</p>
<h3 id="step-1">Step 1</h3>
<h1>Basic HTTP Routing in Golang</h1>
<p>Golang is incredibly powerful. Its standard library has so much to offer, but I think other languages have encouraged the use of external libraries for even the most basic tasks. For example, with JavaScript, most inexperienced developers seem to use jQuery to do simple tasks like selecting an element and replacing its contents. When you and I both know jQuery is way overkill for such a task. <a href="https://leviolson.com/posts/vanilla-js-basics">See my article on Vanilla JS basics</a>.</p>
<p>I believe that in order to be considered an expert in a language, you must at least be able to demonstrate using the core language to achieve your goal. In our current case, HTTP routing. Now to be clear, I don&#39;t think you need to write everything from scratch all the time, but you should have a firm grasp on what is available by the core language, and when you are better suited to use an external library. If you are looking for more advanced HTTP routing, then I would suggest using something like <a href="https://github.com/gin-gonic/gin">gin</a>.</p>
<p>Enough ranting, let&#39;s get to it.</p>
<h2>Assumptions</h2>
<p>I assume you have basic knowledge of the Go language at this point, so if not, it might be worth searching for some entry level basics first. See <a href="https://tour.golang.org">A Tour of Go</a>.</p>
<h2>Let&#39;s begin</h2>
<p>The accompanying repo for the code produced in this article is located <a href="https://github.com/leothelocust/basic-http-routing-in-golang">on github</a>.</p>
<h3>Step 1</h3>
<p>Here is our basic folder structure for this basic http routing example:</p>
<pre><code> basic-http-routing-in-golang/
main.go
</code></pre>
<p>As a starting point our
<code>main.go</code> file looks like this:</p>
main.go</code></pre>
<p>As a starting point our <code>main.go</code> file looks like this:</p>
<pre><code> package main
import (
@ -34,32 +32,28 @@
func main() {
fmt.Println(&quot;Hello HTTP&quot;)
}
</code></pre>
<h3 id="step-2">Step 2</h3>
<p>Now starting at a very basic level, we can leverage the
<a href="https://golang.org/pkg/net/http/#HandleFunc">
<code>http.HandleFunc</code>
</a> method.</p>
}</code></pre>
<h3>Step 2</h3>
<p>Now starting at a very basic level, we can leverage the <a href="https://golang.org/pkg/net/http/#HandleFunc"><code>http.HandleFunc</code></a> method.</p>
<p>It is very simple to use and its signature is easy to understand.</p>
<pre><code> func HandleFunc(pattern string, handler func(ResponseWriter, *Request))
</code></pre>
<p>Which basically means,
<code>http.HandleFunc(&quot;/url&quot;, routingFunction)</code> where
<code>routingFunction</code> looks like this:</p>
<pre><code> func HandleFunc(pattern string, handler func(ResponseWriter, *Request))</code></pre>
<p>Which basically means, <code>http.HandleFunc(&quot;/url&quot;, routingFunction)</code> where <code>routingFunction</code> looks like this:</p>
<pre><code> func routingFunction(w http.ResponseWriter, req *http.Request) {
fmt.Fprint(w, &quot;Hello HTTP&quot;)
}
</code></pre>
<p>With
<code>fmt.Fprint()</code> we can pass an
<code>http.ResponseWriter</code> and a message to display. Our browser will now look like this when we visit the
<code>/url</code> endpoint.</p>
<p>
<img src="https://leviolson.com/images/step2-browser-output.png" alt="Browser Output for Step 2 - Hello HTTP">
</p>
<p>Here is what
<code>main.go</code> looks like at this point:</p>
}</code></pre>
<p>With <code>fmt.Fprint()</code> we can pass an <code>http.ResponseWriter</code> and a message to display. Our browser will now look like this when we visit the <code>/url</code> endpoint.</p>
<p><img alt="Browser Output for Step 2 - Hello HTTP" src="https://leviolson.com/images/step2-browser-output.png"/></p>
<p>Here is what <code>main.go</code> looks like at this point:</p>
<pre><code> package main
import (
@ -75,20 +69,20 @@
func helloHTTP(w http.ResponseWriter, req *http.Request) {
fmt.Fprint(w, &quot;Hello HTTP&quot;)
}
</code></pre>
<p>Now we could stop there, as this is a &quot;basic&quot; http routing example, but I think it isn't quite useful as an example
yet, until we start to see something slightly more practical.</p>
<h3 id="step-3">Step 3</h3>
<p>So let's add a
<code>NotFound</code> page when we don't match a pattern in
<code>HandleFunc</code>. It's as simple as:</p>
}</code></pre>
<p>Now we could stop there, as this is a &quot;basic&quot; http routing example, but I think it isn&#39;t quite useful as an example yet, until we start to see something slightly more practical.</p>
<h3>Step 3</h3>
<p>So let&#39;s add a <code>NotFound</code> page when we don&#39;t match a pattern in <code>HandleFunc</code>. It&#39;s as simple as:</p>
<pre><code> func notFound(w http.ResponseWriter, req *http.Request) {
http.NotFound(w, req)
}
</code></pre>
<p>Here is what
<code>main.go</code> looks like after that:</p>
}</code></pre>
<p>Here is what <code>main.go</code> looks like after that:</p>
<pre><code> package main
import (
@ -109,55 +103,40 @@
func notFound(w http.ResponseWriter, req *http.Request) {
http.NotFound(w, req)
}
</code></pre>
<p>This will match
<code>/hello</code> and use the
<code>HelloHTTP</code> method to print &quot;Hello HTTP&quot; to the browser. Any other URLs will get caught by the
<code>/</code> pattern and be given the
<code>http.NotFound</code> response to the browser.</p>
}</code></pre>
<p>This will match <code>/hello</code> and use the <code>HelloHTTP</code> method to print &quot;Hello HTTP&quot; to the browser. Any other URLs will get caught by the <code>/</code> pattern and be given the <code>http.NotFound</code> response to the browser.</p>
<p>So that works, but I think we can go further.</p>
<h3 id="step-4">Step 4</h3>
<p>We need to give ourselves something more specific than the simple contrived
<code>/hello</code> endpoint above. So let's assume we are needing to get a user profile. We will use the url
<code>/user/:id</code> where
<code>:id</code> is an identifier used to get the user profile from our persistance layer (i.e. our database).</p>
<p>We'll start by creating a new method for this GET request called
<code>userProfile</code>:</p>
<h3>Step 4</h3>
<p>We need to give ourselves something more specific than the simple contrived <code>/hello</code> endpoint above. So let&#39;s assume we are needing to get a user profile. We will use the url <code>/user/:id</code> where <code>:id</code> is an identifier used to get the user profile from our persistance layer (i.e. our database).</p>
<p>We&#39;ll start by creating a new method for this GET request called <code>userProfile</code>:</p>
<pre><code> func userProfile(w http.ResponseWriter, req *http.Request) {
userID := req.URL.Path[len(&quot;/user/&quot;):]
fmt.Fprintf(w, &quot;User Profile: %q&quot;, userID)
}
</code></pre>
<p>Notice that we get the URL from the
<code>req</code> variable and we treat the string returned from
<code>req.URL.Path</code> as a byte slice to get everything after the
<code>/user/</code> in the string.
<strong>Note: this isn't fool proof,
<code>/user/10ok</code> would get matched here, and we would be assigning
<code>userID</code> to
<code>&quot;10ok&quot;</code>.</strong>
</p>
<p>Let's add this new route in our
<code>main</code> function:</p>
}</code></pre>
<p>Notice that we get the URL from the <code>req</code> variable and we treat the string returned from <code>req.URL.Path</code> as a byte slice to get everything after the <code>/user/</code> in the string. <strong>Note: this isn&#39;t fool proof, <code>/user/10ok</code> would get matched here, and we would be assigning <code>userID</code> to <code>&quot;10ok&quot;</code>.</strong></p>
<p>Let&#39;s add this new route in our <code>main</code> function:</p>
<pre><code> func main() {
http.HandleFunc(&quot;/hello&quot;, helloHTTP)
http.HandleFunc(&quot;/user/&quot;, userProfile)
http.HandleFunc(&quot;/&quot;, notFound)
log.Fatal(http.ListenAndServe(&quot;:8080&quot;, nil))
}
</code></pre>
<p>
<em>Note: that this pattern
<code>/user/</code> matches the trailing
<code>/</code> so that a call to
<code>/user</code> in the browser would return a
<code>404 Not Found</code>.</em>
</p>
<h3 id="step-5">Step 5</h3>
<p>Ok, so we have introduced some pretty severe holes in the security of our new HTTP router. As mentioned in a note above,
treating the
<code>req.URL.Path</code> as a byte slice and just taking the last half is a terrible idea. So let's fix this:</p>
}</code></pre>
<p><em>Note: that this pattern <code>/user/</code> matches the trailing <code>/</code> so that a call to <code>/user</code> in the browser would return a <code>404 Not Found</code>.</em></p>
<h3>Step 5</h3>
<p>Ok, so we have introduced some pretty severe holes in the security of our new HTTP router. As mentioned in a note above, treating the <code>req.URL.Path</code> as a byte slice and just taking the last half is a terrible idea. So let&#39;s fix this:</p>
<pre><code> var validPath = regexp.MustCompile(&quot;^/(user)/([0-9]+)$&quot;)
func getID(w http.ResponseWriter, req *http.Request) (string, error) {
@ -167,19 +146,18 @@
return &quot;&quot;, errors.New(&quot;Invalid ID&quot;)
}
return m[2], nil // The ID is the second subexpression.
}
</code></pre>
}</code></pre>
<p>Now we can use this method in our code:</p>
<pre><code> func userProfile(w http.ResponseWriter, req *http.Request) {
userID, err := getID(w, req)
if err != nil {
return
}
fmt.Fprintf(w, &quot;User Profile: %q&quot;, userID)
}
</code></pre>
<h2 id="conclusion">Conclusion</h2>
<p>For now, I'm calling this &quot;Basic HTTP Routing in Golang&quot; article finished. But I do plan to add more to it as time
allows. Additionally, I'd like to create a more advanced article that discusses the ability to respond to not only GET
requests, but also POST, PUT, and DELETE HTTP methods. Look for an &quot;Advanced HTTP routing in Golang&quot; article
in the future. Thanks for reading this far. I wish you well in your Go endeavors.</p>
}</code></pre>
<h2>Conclusion</h2>
<p>For now, I&#39;m calling this &quot;Basic HTTP Routing in Golang&quot; article finished. But I do plan to add more to it as time allows. Additionally, I&#39;d like to create a more advanced article that discusses the ability to respond to not only GET requests, but also POST, PUT, and DELETE HTTP methods. Look for an &quot;Advanced HTTP routing in Golang&quot; article in the future. Thanks for reading this far. I wish you well in your Go endeavors.</p>

+ 0
- 0
posts/project-led.html View File


+ 9
- 0
posts/project-led.json View File

@ -0,0 +1,9 @@
{
"title": "Project LED : A minimal terminal text editor - Levi Olson",
"permalink": "/posts/project-led",
"created_at": "2019-02-14T10:31:19-06:00",
"created_at_short": "2019-02-14",
"post_title": "Project LED : Minimal Terminal Text Editor",
"active": "posts",
"content_file": "prodject-led.html"
}

+ 74
- 69
posts/vanilla-js-basics.html View File

@ -1,79 +1,84 @@
<h1 id="vanilla-js-basics">Vanilla JS Basics</h1>
<p>
<em>Warning: This article turned out to be a bit of rant. So if you are the type to get offended when I say negative things
about JavaScript, you are welcome to leave.</em>
</p>
<p>JavaScript is what I consider to be an &quot;easy&quot; language. Now what do I mean by that? Well, its usually the first
<em>scripting</em> language that new developers learn, and you can get started with very little &quot;training&quot;. It
has a relatively simple syntax. It can be very powerful. So from my point of view, its an easy language to pick up. And
therein lies the problem.</p>
<p>So many of the JavaScript programmers out there today hear the term &quot;JavaScript&quot; and think in there mind &quot;jQuery&quot;.
Now that's great to have that kind of brand recognition if you are jQuery, but if you are looking to be an efficient
programmer that doesn't put holes in everything you make, you may want to consider that JavaScript is NOT jQuery.</p>
<p>Additionally, we need to start thinking about the consequences of using third-party libraries for everything. Longer load
times, additional security risks, more memory consumption, and the list goes on.</p>
<p>I want to give you at least a few little snippets of vanilla JavaScript that will get you on your way to not importing jQuery
on every project as a
<em>step 1</em>. It should be near the end of your steps and only as needed.</p>
<p>
<em>Disclaimer: Vanilla JavaScript will be longer (i.e. more verbose), but this isn't always a bad thing. Keep in mind that
we are eliminating the import of another package, and all the bloat that comes with it.</em>
</p>
<h2 id="assumptions">Assumptions</h2>
<p>For starters, I'm assuming that you getting this far means that you at least have heard of JavaScript. If you have not heard
of jQuery,
<strong>leave now</strong>, I don't want &quot;introducing someone to jQuery&quot; to be what you get out of this.</p>
<p>Let's begin...</p>
<h3 id="selecting-element-in-the-dom">Selecting Element in the DOM</h3>
<h1>Vanilla JS Basics</h1>
<p><em>Warning: This article turned out to be a bit of rant. So if you are the type to get offended when I say negative things about JavaScript, you are welcome to leave.</em></p>
<p>JavaScript is what I consider to be an &quot;easy&quot; language. Now what do I mean by that? Well, its usually the first <em>scripting</em> language that new developers learn, and you can get started with very little &quot;training&quot;. It has a relatively simple syntax. It can be very powerful. So from my point of view, its an easy language to pick up. And therein lies the problem.</p>
<p>So many of the JavaScript programmers out there today hear the term &quot;JavaScript&quot; and think in there mind &quot;jQuery&quot;. Now that&#39;s great to have that kind of brand recognition if you are jQuery, but if you are looking to be an efficient programmer that doesn&#39;t put holes in everything you make, you may want to consider that JavaScript is NOT jQuery.</p>
<p>Additionally, we need to start thinking about the consequences of using third-party libraries for everything. Longer load times, additional security risks, more memory consumption, and the list goes on.</p>
<p>I want to give you at least a few little snippets of vanilla JavaScript that will get you on your way to not importing jQuery on every project as a <em>step 1</em>. It should be near the end of your steps and only as needed.</p>
<p><em>Disclaimer: Vanilla JavaScript will be longer (i.e. more verbose), but this isn&#39;t always a bad thing. Keep in mind that we are eliminating the import of another package, and all the bloat that comes with it.</em></p>
<h2>Assumptions</h2>
<p>For starters, I&#39;m assuming that you getting this far means that you at least have heard of JavaScript. If you have not heard of jQuery, <strong>leave now</strong>, I don&#39;t want &quot;introducing someone to jQuery&quot; to be what you get out of this.</p>
<p>Let&#39;s begin...</p>
<h3>Selecting Element in the DOM</h3>
<p>jQuery</p>
<pre><code> $('#myID')
</code></pre>
<pre><code> $(&#39;#myID&#39;)</code></pre>
<p>Vanilla JavaScript</p>
<pre><code> document.getElementById('myID')
</code></pre>
<p>Again, note that vanilla JavaScript is longer, but its actually more descriptive of what is going on here. Unless you are
familiar with jQuery (yes, I know you are) the jQuery syntax doesn't tell you what its doing.</p>
<h3 id="replace-text-html-in-the-dom">Replace Text/HTML in the DOM</h3>
<pre><code> document.getElementById(&#39;myID&#39;)</code></pre>
<p>Again, note that vanilla JavaScript is longer, but its actually more descriptive of what is going on here. Unless you are familiar with jQuery (yes, I know you are) the jQuery syntax doesn&#39;t tell you what its doing.</p>
<h3>Replace Text/HTML in the DOM</h3>
<p>jQuery</p>
<pre><code> $('#myID').html('here is the replacement')
</code></pre>
<pre><code> $(&#39;#myID&#39;).html(&#39;here is the replacement&#39;)</code></pre>
<p>Vanilla JavaScript</p>
<pre><code> document.getElementById('myID').innerHTML('here is the replacement')
</code></pre>
<p>Very similar eh. However, there is actually some performance gain by using vanilla JavaScript. See
<a href="https://stackoverflow.com/questions/3563107/jquery-html-vs-innerhtml#answer-3563136">here</a>.</p>
<h3 id="click-handling-in-the-dom">Click Handling in the DOM</h3>
<pre><code> document.getElementById(&#39;myID&#39;).innerHTML(&#39;here is the replacement&#39;)</code></pre>
<p>Very similar eh. However, there is actually some performance gain by using vanilla JavaScript. See <a href="https://stackoverflow.com/questions/3563107/jquery-html-vs-innerhtml#answer-3563136">here</a>.</p>
<h3>Click Handling in the DOM</h3>
<p>jQuery</p>
<pre><code> $('#myID').click(function() {
alert('Clicked it!')
})
</code></pre>
<pre><code> $(&#39;#myID&#39;).click(function() {
alert(&#39;Clicked it!&#39;)
})</code></pre>
<p>Vanilla JavaScript</p>
<pre><code> document.getElementById('myID').addEventListener('click', function(e) {
alert('Clicked it!')
})
</code></pre>
<pre><code> document.getElementById(&#39;myID&#39;).addEventListener(&#39;click&#39;, function(e) {
alert(&#39;Clicked it!&#39;)
})</code></pre>
<p>So easy.</p>
<h3 id="advanced-queries-and-iteration">Advanced Queries and Iteration</h3>
<h3>Advanced Queries and Iteration</h3>
<p>jQuery</p>
<pre><code> $('.item').hide()
</code></pre>
<pre><code> $(&#39;.item&#39;).hide()</code></pre>
<p>Vanilla JavaScript</p>
<pre><code> var items = document.getElementsByClassName('.items')
<pre><code> var items = document.getElementsByClassName(&#39;.items&#39;)
for (var i = 0; i &lt; items.length; i++) {
item[i].style.display = 'none'
}
</code></pre>
<p>We're starting to see the verbosity I mentioned above, but again, remember that we aren't loading in a massive third-party
library!</p>
<h3 id="even-more-advanced">Even More Advanced</h3>
<p>See Patrick Kunka's article
<a href="https://blog.wearecolony.com/a-year-without-jquery/">A Year Without jQuery</a>
</p>
<p>Patrick and I agree on many of the same points and his article articulates some helper functions that can be used to perform
more advanced loops, child selection and child indexing. I highly recommend you read through his article.</p>
<h2 id="conclusion">Conclusion</h2>
<p>If you find that your requirements heavily rely on JavaScript for DOM manipulation, or that you need animations such as the
ones provided by jQuery, then don't let me stop you. But if you only need some of what was covered above, or you want
to put a priority on performance, then you should really consider going with plain vanilla JavaScript and leave the dependencies
behind. You won't regret it.</p>
item[i].style.display = &#39;none&#39;
}</code></pre>
<p>We&#39;re starting to see the verbosity I mentioned above, but again, remember that we aren&#39;t loading in a massive third-party library!</p>
<h3>Even More Advanced</h3>
<p>See Patrick Kunka&#39;s article <a href="https://blog.wearecolony.com/a-year-without-jquery/">A Year Without jQuery</a></p>
<p>Patrick and I agree on many of the same points and his article articulates some helper functions that can be used to perform more advanced loops, child selection and child indexing. I highly recommend you read through his article.</p>
<h2>Conclusion</h2>
<p>If you find that your requirements heavily rely on JavaScript for DOM manipulation, or that you need animations such as the ones provided by jQuery, then don&#39;t let me stop you. But if you only need some of what was covered above, or you want to put a priority on performance, then you should really consider going with plain vanilla JavaScript and leave the dependencies behind. You won&#39;t regret it.</p>

Loading…
Cancel
Save