Introduction to Javascript

In this class we'll walk through the basics of javascript. You've already had an introduction to how ruby works in Al's ruby scraping class, and had a bit of html and css in earlier classes. But now we're going to learn JavaScript, which is the progamming language of the browser. Also, you can run it on the server as well using a framework called node.js.

Resources

Honestly, the most important skill you can have when learning to program is knowing where to find help. Here are a few resources that I've found particularly useful:

Basic Objects

Let's start with a simple tour of the various datatypes available in JavaScript.

var number = 1;
console.log(number + number);

var string = "Jeff";
console.log(string.length);
console.log(string + string);
console.log(string + number);

JavaScript also has arrays and objects, arrays are collections of things and you can get things out by using square brackets.

var array = [number, string];
console.log(array.length);
console.log(array[1]);

Objects are like arrays, but to get things out you either use brackets or dots.

var object = {
  number: number,
  string: string
};

console.log(object.string);
console.log(object["string"]);

Functions are fundamental to JavaScript, you can think of them as small sub-programs.

var getNumber = function(obj){
  return obj.number;
};
console.log(getNumber(object));

Functions also have access to variables defined outside of them, so here we can access our object defined above.

function getString() {
  return object.string;
}
console.log(getString());

Functions can also be passed to other functions.

var callFunction = function(fn) {
  return fn();
};
console.log(callFunction(getString));

Controlling Flow

It's not very useful to only have functions that return things and variables that store things, so JavaScript -- and really all programming languages -- allow us to tell the computer to make decisions.

if(object.number > 1) {
  console.log("greater than 1: ", object.number);
} else {
  console.log("less than or equal to 1: ", object.number);
}

Computer's are dumb, but they are very fast at being dumb. Let's do something dumb a million times.

var aMillion = 0;
for(var i = 0; i < 1000000; i++)
  aMillion++;
console.log(aMillion);

We also can ask the computer to do something while something is true.

var run = true;
while(run) {
  run = false;
}
console.log(run);

Or we can ask the computer to choose among a bunch of choices.

var myName = "Jeff";
switch(myName) {
case "Jeff":
  console.log("Your name is Jeff");
  break;
case "Sisi":
  console.log("Your name is Sisi");
  break;
default:
  console.log("I don't know your name");
}

And we can ask JavaScript to do something in the future.

setTimeout(function(){
  console.log("World!");
});
console.log("Hello!");

That's the very basics, and enough to get you started with jQuery, and moving things around a webpage.

Setting up the room

We need to create a webpage that will include a useful JavaScript library called jQuery, and our code. We'll do that using a script tag.

<html>
 <head>
   <link rel="stylesheet" type="text/css" href="styles.css">
   <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.4/jquery.js"></script>
   <script src="app.js"></script>
 </head>
 <body>
 </body>
</html>

Adding a HTML element.

jQuery allows you to very easily manipulate the DOM. Let's create an HTML element and add it to the dom.

$(function(){
  var el = $("<div />");
  el.attr({ id: "box" });
  $("body").append(el);
});

Ok, a lot is going on there. Let's unpack it. We'll start from the inside of the function and work our way out from there.

First, we create an HTML element, that is a div with jQuery. The $ function is how you call jQuery. In this case, we are telling it create a new HTML div. We do that by enclosing the tag name div in angle brackets < />.

Then we assign our div an id of box using the jQuery method attr.

You'll notice that the second call does not have angle brackets. In this case jQuery interprets the argument as a css selector. In this case, we are looking for the body tag.

Finally, we ask jQuery to insert our new element into the body tag, using the jQuery method append.

How do I know what I can do with a jQuery object like this?

$("body");

The jQuery docs are a good resource: https:api.jquery.com/ We can also find out via the devtools in chrome:

console.dir($("body"));

Document ready.

We skipped over this part:

$(function(){

});

What is that? Well, turns out that we have to wait for the browser to be ready for our JavaScript. The browser evaluates things in order. So, we put our script tag at the top of the HTML. But the browser won't know about the body until later. So, we need to wait until the browser knows that the body tag is there. In this case, jQuery can figure out that you've passed a function to it, and tells the browser to call that function after it has parsed the HTML you wrote. You can imagine that jQuery is doing something like this:

var $simple = function(thing){
  if(typeof thing == "string") {
    if(thing[0] == "<") {
      // create element
      return document.createElement("div");
    } else {
      // find something on the page
      return document.querySelector(thing);
    }
  } else if(typeof thing == "function"){
    // tell browser to wait
    return document.addEventListener("load", thing);
  }
};

Document is a global variable that represents the HTML document itself, and you can probably guess what everything does:

  1. document.createElement returns a JavaScript object representing a new HTML element.
  2. document.querySelector returns a JavaScript object representing an element already on the page.
  3. document.addEventListener is weird, and we don't really need to go into it, but trust me when I say that calling that function makes the browser wait until your HTML is loaded to call a function.

We haven't seen yet is that typeof operator yet. typeof tells you what kind of object a variable is. To be honest, you'll almost never need it, I've never used it :)

Let's pause for a second and answer a question you may have. If the simpleQuery function is how jQuery works, why do we need it? Well, every browser implements JavaScript and HTML differently and jQuery fixes evens out those bugs. It also provides some niceties.

Great, let's do something!

So, far we haven't done much. We've seen how to append a new element to an HTML page, and learned a bunch about JavaScript, but we still can't see anything on the page. Let's fix that.

$(function(){
  var el = $("#box");
  el.css({
    width: "100px",
    height: "100px",
    "background-color": "cornflowerblue"
  });
});

Let's unpack that a bit. First of all, all functions passed to jQuery, are executed in order. Secondly, we when we use a pound sign in a call to jquery it tries to get an element by an id. Remember before when we set the id attribute on our element to box? Well this is why we did that.

Then we use jQuery's css function to set the width and height of our element.

Making things move

Ok, so we've seen how we can create an element, and set some css properties on it. Can we do something flashy? Let's play around with css animations.

.animate {
  -webkit-transition: width 1s;
  transition: width 1s;
}
$(function(){
  $("#box").addClass("animate").css({ width: "100%" });
});

That's pretty neat, but what if we only want it to animate when a user clicks?

$(function(){
  $("#box").addClass("animate").css({ width: "100px" });
  $("#box").on("click", function(e) {
    $(this).css({ width: "100%" });
  });
});

The on function is like the addEventListener function we saw earlier, it let's you run some code in response to an event, in this case when a user clicks on our box.

Ok, so what is this there? I'm going to be a bit hand-wavy here, but this is a special keyword in JavaScript. Here, this is our underlying HTML object, which we can pass to jQuery to convert it to a jQuery object. You can learn more about this in Chapter 6 of eloquent JavaScript.

What about doing something when a user hovers over our box? Let's see:

$(function(){
  $("#box").hover(function(){
    $(this).css({"background-color": "red", width: "100%"});
  }, function(){
    $(this).css({"background-color": "cornflowerblue", width: "50%"});
  });
});

There are two functions there, on for when the users mouse enters the Element and one when the mouse exits.

Data Visualization in JavaScript

Let's tie this all together. Let's write a small program to build a histogram based on some data.

$(function(){
  var data = [365, 346, 298, 337, 323, 318, 343, 301, 317, 227];
  var total = 0;
  for(var i = 0; i < data.length; i++)
    total += data[i];

  var container = $("<div />");
  container.css({
    position: "relative",
    width: "500px",
    height: "500px"
  });

  data.forEach(function(it, i){
    var bar = $("<div />");

    bar.css({
      width: 1 / data.length * 100 + '%',
      height: it / total * 100 * 2 + '%',
      "background-color": "cornflowerblue",
      position: "absolute",
      border: "1px solid white",
      bottom: 0,
      left: i / data.length * 100 + '%'
    });

    bar.hover(function(){
      $(this).css({"background-color": "darkseagreen"});
    }, function() {
      $(this).css({"background-color": "cornflowerblue"});
    });

    container.append(bar);
  });

  $("body").append(container);
});