/w4d2-Jan27

Lecture notes for week 4, day 2 of LH labs full-time bootcamp

W4D2

Introduction to Client-Side JavaScript and jQuery

NodeJS Review

NodeJS runs JavaScript server-side

So far, we have rendered our pages using ejs (SSR, server-rendered).

Problem: how do we deal with interactive data coming in and out of the page?

  • Real-time applications
  • Data that changes often

Differences Between NodeJS and Client-Side JavaScript

window replaces process

  • No access to process or process.argv
  • window is global scope; the same as declaring without var, let, or const
  • window is implicit: window.location === location

DOM

Document Object Model

DOM tree example

  • Tree-like structure
  • Composition (vs. inheritence)
  • Like a tree: leaf, root node (html)
  • Hierchical structure

Elements all are Nodes; multiple elements are NodeList instances

JS DOM Interaction

  1. document.getElementById
  2. document.getElementByTagName
  3. document.querySelector
  4. document.querySelectorAll
Method (Singular) Method (Plural) Support
document.getElementById N/A
document.getElementByTagName document.getElementsByTagName
N/A document.getElementsByClassName
document.querySelector document.querySelectorAll 𐄂

document.querySelector and document.querySelectorAll generally preferred

JS Event Handling

Events bubble up unless otherwise prevented.

event bubbling diagram

Node.prototype.addEventListener

Works for any event. List of all the events

JQuery

Client-side JS library used for DOM interaction

Introduced due to inconsistent browser APIs: Internet Explorer vs. Firefox vs. Chrome

Ex.

var list = document.getElementById("list"); // works in all browsers
var list = document.getElementByTagName("ul"); // works still :)
const listItem = document.getElementById("list"); // doesn't work in IE, old Chrome, old FF

document.querySelector and document.querySelectorAll now have good support

Historically, jQuery has been very pervasive on the web due to the inconsistencies of browser support, so we still have to learn it.

$ Selector

Equivalent to document.querySelectorAll, but works in all browsers.

jQuery $ vs. document.querySelectorAll

jQuery returns an Array-like object, whereas document.querySelectorAll returns a NodeList.

Vanilla JS

const celebritiesContainer = document.querySelector(".celebrities");
const celebrities = celebritiesContainer.querySelectorAll(".celebrity"); // a NodeList (not an Array!)

Array.from(celebrities).map((celebrity) => console.log(celebrity.innerText));

jQuery

const $celebritiesContainer = $(".celebrities");
const $celebrities = $celebritiesContainer.find(".celebrity"); // an array of Node(s)

$celebrities.map((celebrity) => console.log($(celebrity).text()));

No need to choose between document.querySelector and document.querySelectorAll; one method to rule them all

.click

Don't use this one; use .on instead

No:

$(document).ready(function() {
	console.log("ready");
});

Yes:

jQuery(function($) {
	console.log("Ready");
});

or:

$(function($) {
	console.log("ready");
});

Note that $ is an alias for jQuery; they are one and the same.

We pass in $ explicity to ensure we have an instance of jQuery as opposed to a competing framework that may use the $ (MooTools).

Dealing with HTML

Roughly 5 options:

  1. .html: renders raw HTML
  2. .append, .prepend (to)
  3. .before, .after

Place your HTML in backticks ```:

const text = "list item text";

const $listItem = $(`
	<li>${text}</li>
`).appendTo("body");

Or place your template in a <template> tag.

<template id="listItemTemplate">
	<li>
		<slot name="list-item"></slot>
	</li>
</template>
const text = "list item text";
const $listItemTemplate = $("#listItemTemplate");
const $body = $("body");

$listItemHTML = $listItemTemplate.clone();
$listItemHTML.find("slot:first").parent().text(text);

$body.append($listItemHTML);

<slot>s tell us where to place dynamic content. We can have as many <slot>s as we want.

<template> tags don't get rendered, so we don't need to hide them. We can have as many <template> tags as we want.

Use back-ticks when placing HTML in your JS for small HTML; use the <template> tag when you have complex markup.

Showing/Hiding

  • .show
  • .hide
  • .toggle
  • .slideToggle
  • .slideIn
  • .slideOut

CSS Methods

  • .css
  • .toggleClass
  • .addClass
  • .removeClass

The above use CSS transforms under the hood. Best to use .toggleClass or .addClass/.removeClass instead.

Also, check out the hidden attribute.

Attributes

.attr("attribute") to get, and .attr("attribute", value) to set

jQuery Conventions

  • Prefix variables with the $: $const $userMenu = $(".menu");
  • Load jQuery via a CDN or NPM
  • Check if .length !== 0 in case the element doesn't exist
  • Start with your container element, then call .find subsequently on that element
  • Run your jQuery code in an IIFE
  • Run your jQuery code in a jQuery() callback or equivalent
  • Use jQuery or don't; choose one or the other
  • Load your <script> tags with defer
  • Separate out your templates in <template> tags (opinion); separate HTML and JS
  • Build your HTML separately, without jQuery, only updating the DOM once

Useful Links