⚡️ 30 Day Vanilla JS ⚡️
Tags: javascript, firstyearincode, 100daysofcode, webdev
Published: 2021-09-01 15:49:19

I have been meaning to take on [Wes Bos' JavaScript30 challenge](https://javascript30.com/), but had no time to spare during my bootcamp regime at Flatiron School. At this moment as I am writing this blog, I already had exposure to Vanilla JS and worked on a [simple trivia app](https://dev.to/fentybit/know-it-all-2kpp), *Know It All.* There are more to JavaScript that I decided to embark on this #JavaScript30. This blog concludes my journey of 30 Day Vanilla JS Challenge. I had much fun! Thank you Wes Bos. 🙌🏼

***

### 🥁  Day 1 JavaScript Drum Kit

The goal is to press any of the displayed keys, and it will give you its assigned sound. `.wav` sound files are already provided in the starter files. By utilizing `querySelector` on `event.keyCode`, I was able to adjust the selected element's `classList` and attached an `addEventListener` on `keydown` to trigger the sound.

![JavaScript Drum Kit](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/akm8cfi95sjjetnjso6g.gif)

***

### ⏰  Day 2 CSS + JS Clock

I learned a few new JS prototype methods on `getHours()`, `getMinutes()` and `getSeconds()`. A bit of mathematical calculations required when trying to update the `style` in order to `transform` the `rotate` degree attributes. The `setInterval` function will trigger updates every second (or 1000 millisecond).

![CSS + JS Clock](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/cf071l88i73khlxbkqoz.gif)

***

### 🎨  Day 3 Playing with CSS Variables and JS

Updating CSS variables with JavaScript is pretty cool! Now I know how to declare `--base`, `--spacing` and `--blur` CSS variables and default values under `:root` in `<style>` element. `change` and `mousemove` event listeners are being utilized to handle changes and update event display.

![Playing with CSS Variables and JS](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/c736d5xpj9ldt8ws6sll.gif)

***

### 🫀  Day 4 Array Cardio Day 1

This is a good overview on JS `filter()`, `map()`, `sort()` and `reduce()` functions. De-structuring assignment was also introduced, and a bit of refactoring exercise on `if else` statement to ternary operator syntax.

![Array Cardio Day 1](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/l6e6yszbb9ljnkitjb70.gif)

***

### 🌁  Day 5 Flex Panel Gallery

FlexBox CSS has personally been a total nightmare for me, but Wes Bos made it so much fun. 😆
I learned a few new CSS attributes such as `display: flex`, `transform: translateY(-100%)` and [DOMTokenList](https://developer.mozilla.org/en-US/docs/Web/API/DOMTokenList/toggle) `toggle()` method.

![Flex Panel Gallery](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/neiywupqgr6yylptmn5i.gif)

***

### ⚡️  Day 6 AJAX Type Ahead

I had previously done extensive `fetch()` requests on my ReactJS/Redux app, [Storybook](https://dev.to/fentybit/storybook-4p2g).

What's new for me in this lesson would be to implement `RegExp` when typing matching words, and adding both `change` and `keyup` add event listeners on the search input.

![AJAX Type Ahead](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ojjhxk0bxrn5spu72p6p.gif)

***

### 🏃🏻‍♀️  Day 7 Array Cardio Day 2

Good brush up on JavaScript methods `some()`, `every()`, `findIndex()`. I have used `new Date()`, but `getFullYear()` was new to me. I have been programming with JavaScript for 4 months, and have to admit their prototype methods are endless. 😱

![Array Cardio Day 2](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xzuzioy56286gamq1htw.gif)

***

### 👩🏻‍🎨  Day 8 Fun with HTML5 Canvas

I really love this canvas mouse play with varying line width and [HSL (Hue, Saturation and Lightness)](https://www.w3schools.com/colors/colors_hsl.asp). The add event listeners include `mousemove`, `mouseup`, `mouseout` and `mousedown` with mouse event attributes defining `offsetX` and `offsetY`. As a start, I had to define the canvas with its `getContext` in `2d` and assign its `strokeStyle`, `lineJoin`, `lineCap` and `lineWidth`. A `draw` function with `event` argument triggers hue changes, `moveTo`, `lineTo`, `stroke()` and `[lastX, lastY]`. 🖌

![Fun with HTML5 Canvas](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/x8wq88e6mwlrqoxkl8z8.gif)

***

### 🛠  Day 9 Dev Tools Domination

I am very used to `console.log`, maybe `console.dir` and sometimes `console.table`. It's good to know that there are others including `console.count`, `console.warn`, `console.error`, `console.info` and `console.assert`. `console.groupCollapsed` and `console.groupEnd` are useful when iterating and grouping each instance independently.

![Dev Tools Domination](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ek0fyu1ipyt2xbn0f2qw.png)

***

### ✔️  Day 10 Hold Shift and Check Checkboxes

I had once done a basic To-Do List app. This one includes a `shift` key feature on which it will allow to check all tasks in-between lists. Pretty neat. There are two main variables; one for `boolean` value and one for `lastItemChecked`.

![Hold Shift and Check Checkboxes](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/uxjamro6dukfkcl82zff.gif)

***

### 🎥  Day 11 Custom Video Player

I would say that I am very new to [HTMLMediaElement](https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement) interface, to be specific the [HTMLVideoElement](https://developer.mozilla.org/en-US/docs/Web/API/HTMLVideoElement) elements. The task is to create a basic video player where you can trigger `play` / `pause` button, adjust `volume`, slow / fast `motion` and rewind / forward `progress` bar.

![Custom Video Player](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/47wchhrguvc2kz6gjj3n.gif)

***

### ⌨️  Day 12 Key Sequence Detection (KONAMI CODE)

If you grew up in the 80s and 90s, you are probably familiar with pressing `up` `up` `down` `down` `left` `right` `left` `right` `B` `A` and the `start` button on the controller is a cheat code in the video gaming industry. I am creating something similar! The `secretCode` could be anything, and I utilized `window.addEventListener` on `keyup` to get a matching keypress sequence. Every time a keypress array combination matches the `secretCode`, it will display a [unicorn](https://www.cornify.com/js/cornify.js) image.

![Key Sequence Detection (KONAMI CODE)](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8acfdtm87o5itmdo9bz5.gif)

***

### ⏬  Day 13 Slide In on Scroll

The goal is as you are scrolling down the page, an image to slide in. A `debounce` function is defined to delay milliseconds upon invocation when I have an add event listener, `scroll`. Original state of the images are currently hidden, and as I am scrolling down, I can `add` the `active` class style. The solution can be as simple as selecting all of the images in a variable, and loop over each one in order to check its *truthy* or *falsey*. The condition is *truthy* as I am reaching half image height in pixel for the image to scroll in.

![Slide In on Scroll](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/cfwrxio3830ekhnzij9l.gif)

***

### 💬  Day 14 Object and Arrays - Reference vs. Copy

Another good JS reminder on reference versus copy, `Object.assign` and spread operator implementation. I guess that's all I have to say. 😆

![Object and Arrays - Reference vs. Copy](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4ab2uml0adl6x6qpol0z.gif)

***

### 🌮  Day 15 LocalStorage and Event Delegation

Our web browser has a built-in `localStorage`, and is capable to retain lightweight data inputs including page refresh. I can send each input with `localStorage.setItem`. In order to avoid losing `items` as page refreshes, I can set `items` to `localStorage.getItem`. The toggle actions can be triggered with an add event listener, `click`, and boolean `true` or `false` value.

![LocalStorage and Event Delegation](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pos9dbp7e8dkwjpbw20a.gif)

***

### 🔥  Day 16 CSS Text Shadow Mouse Move Effect

You can play a lot with CSS on `offsetWidth` and `offsetHeight`. I can set the `text.style.textShadow` of various `x` and `y` setbacks with various `rgba` values. Fairly simple, yet fun!

![CSS Text Shadow Mouse Move Effect](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/nrdsrafgfepfjshtmmem.gif)

***

### 🎸  Day 17 Sorting Band Names without Articles

An array of bands are provided in the `bands` array, and the goal is to sort alphabetically while ignoring `a`, `the` and `an`. That means `Counterparts` will come before `A Skylit Drive` since `S` comes after `C`. With simple Regex trick, I can utilize matching groups of `(a |the |an )/i`. The global `-i` denotes insensitive case, and I can iterate each band with a `sort` function.

![Sorting Band Names without Articles](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dqzyji7tjqhc12t3aa62.png)

***

### ⌛️  Day 18 Tally String Times with Reduce

Given a collection of `data-time` with minutes and seconds attributes, I want to add all of the given time duration with a `reduce` function. For a start, create an array of `data-time` collection, iterate each to extract its `.dataset.time` and convert it from string type to integer with `parseFloat` function. With `reduce` function and modulo `%` operator, I should be able to retrieve total seconds, and convert it back to hours, minutes and seconds.

![Tally String Times with Reduce](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/o5k28pj9n9pd28j1qtaq.gif)

***

### 📸  Day 19 Unreal Webcam Fun

This whole exercise is new to me. I learned there is an add event listener, `canplay`. A variable `pixels` is retrieved from `.getContext('2d')` and `.getImageData(0, 0, width, height)`. Later on I can play with the RGB value by adjusting the pixels data.

![Unreal Webcam Fun](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2ar7hzeiglvjhhekg1p3.gif)

***

### 🎤  Day 20 Native Speech Recognition

While it is not perfect, I am in awe that we can do a speech recognition in the browser without any libraries or external API. I triggered a `new SpeechRecognition()`, and set the `.interimResults` to `true` in order to accept more inputs. This allows moving on to the next paragraph when a speaker pauses their speech.

![Native Speech Recognition](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1enuu1j39bf4utkboosr.gif)

***

### 🧭  Day 21 Geolocation based Speedometer and Compass

This application would need an iOS Simulator, and it has a built-in speed and compass automation. For example use case, the speed displayed mimics the behavior of a city bicycle ride. `navigator.geolocation.watchPosition` is invoked to update the arrow and speed.

```js
const arrow = document.querySelector(".arrow");
const speed = document.querySelector(".speed-value");

navigator.geolocation.watchPosition(
  (data) => {
    speed.textContent = data.coords.speed;
    arrow.style.transform = `rotate(${data.coords.heading}deg)`;
  }
);
```

![Geolocation based Speedometer and Compass](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/uf96sl189k7npzkus09q.gif)

***

### 🔗  Day 22 Follow Along Links

The goal would be to highlight all of the links as I hover over the page. First thing I used `querySelectorAll` on `"a"` link attributes. I can add an event listener `mouseenter` and invoke a function to highlight a link. Inside this function, I can utilize `getBoundingClientRect()` and it provides `bottom`, `height`, `left`, `right`, `top` and `width` properties. With all of these coordinate elements, I can assign each `style.width`, `style.height` and `style.transform` pixels accordingly.

![Follow Along Links](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ydukekulpyaq7z3j4yuj.gif)

***

### 🗣  Day 23 Speech Synthesis

This is akin to building a simple screen reader. `SpeechSynthesisUtterance` carries language, text, voice, volume, pitch and other attributes. I can add an event listener `voiceschanged` on `speechSynthesis` and add a function in order to select a voice. For this lesson, I will limit our voices selections strictly to english language. A `boolean` truthy and falsey value can be utilized on a toggle function on the `stop` and `speak` button.

![Speech Synthesis](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ygoj3iwqtrk5ajecvm6h.gif)

***

### 🗒  Day 24 Sticky Nav

It would be nice to have the top nav bar to stay as a user scrolling down the page. The effort is less on setting the script aside from checking a condition when `window.scrollY` is more than top of the nav bar.

![Sticky Nav](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/izp4aa3nse6g9rqttmh0.gif)

***

### 🥍  Day 25 Event Capture, Propagation, Bubbling and Once

`addEventListener` has edge cases. The event bubbling can occur when I capture a selected element. If it happens to be a child element, it should also invoke its parent elements. I can apply similar behavior from parent element to its children elements by adding a key value, `capture: true`. When I select a parent element, it will run the function all the way down calling all of its children elements. `e.stopPropagation()` can stop this event bubbling. Once implemented, when I select the child element, it will not trigger its parent elements. The `once: true` only allows a one-time add event listener.

![Event Capture, Propagation, Bubbling and Once](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ns1c0x63ch6nbngyr494.gif)

***

### 🪢  Day 26 Stripe Follow Along Dropdown

This is a creative way to set up a div element where each dropdown follows its respective links sizes. A function can be invoked along with `mouseenter` and `mouseleave` add event listeners. It is as simple as adding `css` class as I click (or hover above) the link, and remove the class as I move away (or hover away from) the link.

![Stripe Follow Along Dropdown](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ul3wxegq0yo5y6m9p32v.gif)

***

### 🥍  Day 27 Click and Drag to Scroll

There will be four add event listeners, `mousedown`, `mouseleave`, `mouseup` and `mousemove`. I can set the `isDown` variable as boolean, and set it as `false` on both `mouseleave` and `mouseup` when it is no longer on the clicked state. For the `mousemove` add event listener, if the `isDown` is false, I can stop the function from running. I had to extract the `event.pageX` value in order to do a bit of math calculations as sliding horizontally with the `.offsetLeft` and `.scrollLeft` attributes.

![Click and Drag to Scroll](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/lw0k9pepq5undl8alm45.gif)

***

### 🏎  Day 28 Video Speed Controller UI

This challenge is an extension of day 11 task on custom video player. When I am watching a youtube video, it's normal to adjust the video speed. This is exactly that! There is a lot more on playing around with math calculations in order to set the playback rate, and I can encapsulate this behavior through a function which would be invoked through an add event listener, `mousemove`.

![Video Speed Controller UI](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6ibv0g1354n2c7pw1ezq.gif)

***

### ⌚️  Day 29 Countdown Clock

Similar approach to day 2 challenge. Convert the seconds available to minutes and hours, and set a `.reset()` function whenever the add event listener `click` or `submit` a new selection.

![Countdown Clock](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ixgqqfrfizwv26px6rxa.gif)

***

### 🐰  Day 30 Whack A Mole Game

This is probably my most favorable one, and of course it's a game with plain JS. 😆

There are a few functions providing random time, random holes where the mole showing up, and adding score when user successfully whack the mole.

![Whack A Mole Game](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xuouz8ckf9yzbuo6mfwc.gif)

***
<center>[**fentybit**](https://fentybit.me/) | [GitHub](https://github.com/fentybit) | [Twitter](https://twitter.com/fentybit) | [LinkedIn](https://www.linkedin.com/in/fentybit/)</center>