JavaScript30 - Day 11

| Comments

Day 11 of #javascript30 is dealing with controlling a video player.

Like with the <audio> element, I was amazed at how simple the interaction with the player is in the <video> element. I learned how to control volume, skipping and the progress bar. Neat! Once again it blew my mind how many events you can listen for. Here is a list of media events and listening on them instead of trying to keep your own state for example the play button makes a ton of sense.

Flexbox was used in the lesson to control the controls and the super handy flex-basis was used for the progress bar in percent. Simple and elegant.

For the sliders for volume and playback rate, the function used in the lesson used the name of the event it was listening for to set the value. Sorta like this:

video[this.name] = this.value;

Where this is the event. The name of the events in this case was either playbackRate or volume, so it the could also be written like this:

if (this.name === 'volume') {
    video.volume = this.value;
}
else if (this.name === 'playbackRate') {
    video.volume = this.value;
}

.. but the first piece of code is much easier to use and understand once you get over the initial confusion thinking — wait.. Is video an array?. Obviously this will only work if the event names and the property names are the same.


JavaScript30 - Day 10

| Comments

Day 10 of #javascript30 seems simple enough. Check multiple checkboxes when holding shift down. It was pretty hard, though.

This one is a prime example of why only practice makes you a good JavaScript programmer. It's a pretty common UI thing - most email clients use it, so really good call by Wes to include this one in the lessons. I find that in JavaScript there is a lot of UI interaction that I am so bad at because I don't use it in PHP and therefore I just haven't done it enough. And that makes a pretty simple task like this one into something that takes a good while for me to figure out. Should I keep a boolean with state? Should I use slice on the array instead of looping over the whole thing? I simply don't know best practices or pros/cons for these things. This solution loops over the array of checkboxes and holds a boolean if we are in between lasted checked box and the box currently being checked.

There was only one language concept I didn't know that got introduced in this one. And that was that there is a shiftKey property on the MouseEvent. My first implementation had listeners on the keyup and down on the shift key, and it was kinda messy.


JavaScript30 - Day 9

| Comments

Day 9 of #javascript30 is about what you can do with the browser's dev tools to help you in your code.

Inside console.log you can interpolate strings like in PHP's sprintf(). You can also just use the backticks from ES6.

There are a number of methods you can call on the Console object - it's worth checking that list out. One in particular I think is cool: console.assert(). It only prints if what is inside the parentheses evaluates to true. While developing it could be a good idea to use that for some assumptions you have. If the console stays quiet, you're assuming right!

const date = new Date();
// Nothing is in the console.
console.assert(date.getFullYear === date.getFullYear, `Dates don't match`);
// See screenshot below.
console.assert(date.getFullYear !== date.getFullYear, `Dates don't match`);

console.assert()


JavaScript30 - Day 8

| Comments

Day 8 of #javascript30 is playing around with canvas and drawing colorful things in the browser.

You don't actually draw on the the <canvas> - you draw on the 'context' that you get from the canvas - which can be 2D or 3D. Todays lesson is focusing on 2D and you can do a ton of cool stuff with that, so go check out the list of functions that CanvasRenderingContext2D offers. Lines, shapes, text and so on.

What made todays lesson super cool is the use of a variable that is used to increment the hue on the lines we are drawing by setting its strokeStyle. This made it so that I was not just drawing a monochrome line, but a line in all the colors of the rainbow. UNICORN BOWELS!

Unicorn Bowels

Destructuring assignment

In JavaScript the equivalent to PHP's list() is the destructuring assignment. So the idea is that you can assign values to variables from an array like so:

var a, b, rest;
[a, b] = [10, 20];
console.log(a); // 10
console.log(b); // 20

I'm not a big fan of that syntax. Not in PHP either. I have yet to see a case where it makes a ton of sense.


JavaScript30 - Day 7

| Comments

Day 7 of #javascript30 is another array workout. I learn about some() and every() and feel good about it.

Arrays, chapter II

This time we are doing more filtering and searching in arrays. Some of the filtering uses Date — an old nemesis of mine. It's actually OK simple to use and I learned that with parentheses you can call functions on an object like this:

const year = ((new Date()).getFullYear();

rather than:

const date = new Date();
const year = date.getFullYear();

some()

some() will check if any item in the array passes some condition. It returns true if any item passes the condition.

every()

every() is a lot like some(), only this one returns true only id all items pass a condition.

splice()

splice() is a little tricky to understand because it can do many different things depending on what arguments you pass it. One thing that is super important to note, is that it mutates the array it is called on. MDN has a list of array functions that modify the array that is worth reading and understanding.

A couple of examples. Note that the array is modified!

const tapirTypes = ["Baird's", 'Malayan', 'Brazilian', 'Rabbit', 'Mountain'];
// Remove the animal that is not a tapir.
tapirTypes.splice(3, 1);
console.log(tapirTypes);
// [ "Baird's", "Malayan", "Brazilian", "Mountain" ]

// Add the newest discovered tapir to index 1.
tapirTypes.splice(1, 0, 'Kabomani');
console.log(tapirTypes);
// [ "Baird's", "Kabomani", "Malayan", "Brazilian", "Mountain" ]

find()

find() will search your array with the callback function you give it, and return the value of the first element that meets the callback function's test criteria. If nothing is found that satisfies the criteria, it returns undefined.

findIndex()

findIndex() is just like find(), but it returns the index of the item that satisfied the callback function test criteria. If nothing was found it returns -1.


JavaScript30 - Day 6

| Comments

Day 6 of #javascript30 is an ajax type ahead form. I learned about the fetch API, promises, asynchronicity, and I might finally understand 'const'.

Fetch API

In the past I have used jQuery's ajax(), get(), or getJSON() for requesting stuff or I have gone to Stack Overflow and copied an XMLHttpRequest like the one below because there was no way I'd remember how to do that from time to time.

var xmlHttp = new XMLHttpRequest();
  xmlHttp.onreadystatechange = function() {
    if (xmlHttp.readyState == 4 && xmlHttp.status == 200)
      console.log(xmlHttp.responseText);
  }
  xmlHttp.open("GET", endpoint, true); // true for asynchronous
  xmlHttp.send(null);

It so much easier to use fetch():

let cities = [];

fetch(endpoint)
  .then(blob => blob.json())
  .then(data => cities.push(...data));

Promises

fetch() returns a Promise object and when the data has been fetched at some point, the code in the then()s is executed. It is an asynchronous call, so it will be executed at some point. This is important and I actually ran into some problems with console.loging my results. My cities array was empty, but if I console.loged the data inside the call to then(), I had the array filled? It was a good learning experience to run into because I realized the asynchronousness (is that a word?) of the promises. I went to Stack Overflow and copied a function that would "sleep" for 2 seconds and then I could console.log my array of cities. Slow internet connection made me understand promises better. Thanks, wonky internet connection!

const finally clicked for me

I finally understood what const is in JavaScript. It is not the same as a constant in PHP, where the value cannot change, so they were a little confusing to me. I went and read the documentation and this part sums it up nicely:

The const declaration creates a read-only reference to a value. It does not mean the value it holds is immutable, just that the variable identifier cannot be reassigned. For instance, in the case where the content is an object, this means the object's contents (e.g. its parameters) can be altered.

So you can change a const, just not reassign it.

RTFM

This lesson taught me a lot and I took my time reading the documentation for the things I was using. It can hardly surprise anybody that reading the manual is a good idea, but I am actually pleasantly surprised at how good and very readable the docs on MDN (Mozilla Developer Network) are. So if you are also trying to learn more JavaScript, I really recommend spending some time just reading about what you are learning instead of what I normally do which is just hunting for something to copy paste.


JavaScript30 - Day 5

| Comments

This lesson from #javascript30 is showcasing some neat stuff you can do in CSS with Flexbox. While I have used that a couple of times, I feel a little bit about flexbox as I do about JS. I'm not going to get better at it unless I practice. I noticed that the Wes Bos has a 20 video course called What The Flexbox?. I'll definitely check that out. I really like this format.

Transitions and transforms

I love how I am learning how these two go together to make cool effects. Again we use the event transitionend to animate stuff a little extra. If you console.log the event.propertyName it will tell you what is transitioning. Because Safari uses 'flex-grow' instead of 'flex' like all the other browsers we just look for the string 'flex' in the propertyName.

if (e.propertyName.includes('flex')) {
   this.classList.toggle('open-active');
 }

The transition uses cubic-bezier(). I am totally fine with not understanding the math of it, and I found this cool tool to help visualize what the arguments to it do.

include()

I really like the includes() method. It is simpler than for instance PHP's strpos(), because all it does is tell you if a substring is in a string and not where. Keep in mind that include() is case sensitive.

There is also an include() for arrays — same concept and nice and simple.


JavaScript30 - Day 4

| Comments

Arrays

Mr. #javascript30, Wes says that he became a much better programmer when he forced himself to get really good at the array methods. I totally agree that this is central to be good at in most programming languages. Today he talked about these methods in particular:

These are all methods that exist in PHP too, so not many surprises for me there. Wes called them "a gateway drug for functional programming" and if you have dabbled a little with that it makes sense.

I saw this tweet explaining some of the methods and I couldn't help love it:

I didn't know about Array.from() that will make an iterable into an old fashioned array, so you can use that to make for instance a NodeList into an array so you can call map(), reduce(), or whatever array method on it. You can also make something into an array with the spread syntax like so:

const arr = [...cat.querySelectorAll('a')];

Logging arrays and objects

I had totally forgotten about console.table() — I should use that more. It formats like this: console.table()


JavaScript30 - Day 3

| Comments

Day 3 of #javascript30 is using CSS variables and manipulating them with JS. I got my mind blown and I learned about the :root pseudo-element.

CSS variables

The browser support for CSS variables is not great yet. They also have a little bit of a funky syntax with the --:

element {
  --spacing: 10px;
}

That said, I got pretty excited about the cool stuff you can do with them together with JavaScript. I can't wait for better adoption for them but there are hopefully also some polyfills for them out there.

Here is what blew my mind. You can manipulate the variables from JavaScript and the browser updates the CSS. Like this for instance:

var spacing = 12;
document.documentElement.style.setProperty('--spacing', `${spacing}px`);

Boom! I can potentially update hundreds of CSS properties with that line of JavaScript. Nice!

:root pseudo-element

I also learned about the :root pseudo-element. CSS variables declared there are global but you can override variabels on any element on the page like you are used to. CSS still cascades.


JavaScript30 - Day 2

| Comments

Day 2 of #javascript30 is using CSS transform to rotate the hands on a clock.

Manipulating CSS

A HTMLElement has a style property that can be accessed and manipulated like this for instance:

document.querySelector('.second-hand').style.transform = `rotate(${secondsDegrees}deg)`;

Vanilla JS has a toggle() that works just like jQuery's toggleClass(). In fact the classList has a couple of very handy functions that are a lot like stuff jQuery will give you.

Template Literals

The string in back-ticks in the code above is using a Template Literal and I love them. They make it so much easier to write some HTML in JS and to get variable in strings without concatenating them. To use a variable in the string, use the ${yourVar} notation. You can even do stuff like this:

var firstVar = 2;
var secondVar = 2;
console.log(`${firstVar} plus ${secondVar} is ${firstVar + secondVar}`);

and that will output "2 plus 2 is 4". There is also Tagged Template Literals - that will let you apply a function to the variables you "pass in" to the template literal. Pretty neat.