JS230 DOM and Asynchronous Programming with JavaScript
JS230 Quiz 2: Select all statements that are true about an Event object:
- It is an object that contains information about what happened and where it happened. Choice B: Quoting MDN article: "If attaching a handler function to an element using addEventListener, the value of this inside the handler is a reference to the element. It is the same as the value of the currentTarget property of the event argument that is passed to the handler." Choice C: It is not just users. The passage of time can trigger the creation of an event object, or even the browser or another application.
Choose the statements that best describe the XMLHttpRequest object:
- The XMLHttpRequest object is a browser API whose original use was to fetch XML documents. - The XMLHttpRequest object can be used to request an HTML document with JavaScript.
Example: Submitting a Form via XHR: There are three steps to submitting a form using JavaScript: What are they?
1.) Serialize the form data. 2.) Send the request using XMLHttpRequest. 3.) Handle the response.
What is the document node?
A node which represents the entire HTML document. It's the top-most DOM node; that is, it's the parent of all nodes in the DOM. We can use toString to determine that document is an HTMLDocument element.
Javascript event: e.currentTarget VS. e.target
Basically, events bubble by default so the difference between the two is: - target is the element that triggered the event (e.g., the user clicked on) - currentTarget is the element that the event listener is attached to.
Resource Oriented Thinking Eamples: translating verb-oriented functionality into noun- or resource-oriented actions
Here are some examples of how real-world objectives could be mapped into interactions with RESTful APIs: Keep in mind, Sometimes performing what initially appears to be a single action will translate into multiple requests to a RESTful API.
A RESTful API Template
Here is one more table, only this time it is a template for any resource. That's right- any resource at all! Profiles, products, ingredients, automobiles, flights, money transfers, payments... anything. By following REST conventions, most of the decisions a designer has to make turn into: What resources will be exposed? API consumers mostly need to ask: what resource will allow me to achieve my goal?
The jQuery Function: The jquery Property
If you're unsure whether a variable or property references a jQuery object, you can check the jquery property: console.log($content.jquery); If the property exists and is a version number that matches the jQuery version, you know that you're dealing with an object produced by jQuery.
What does the Content-Type header mean?
It describes the format of the response body.
What is the Document Object Model? (DOM)
It is an in-memory object representation of an HTML document. It provides a way to interact with a web page using JavaScript and provides the functionality needed to build modern interactive user experiences.
Adding event listeners of the same type to the same element. Does one overwrite the other?
It is interesting to note that adding an event listener of the same type — "click" — to the same element doesn't overwrite the first one that was added.
What does document.querySelector( ) do?
It is used to get a reference to one of the DOM nodes. This method returns the first node in the DOM that matches the specified CSS selector. There's a chicken-and-egg problem, though: to find a node with querySelector, you must first have a node that you can use to call the method. To solve this, we use the document node. Since document is the parent of all nodes in the DOM, we can use it to call querySelector and search the entire DOM for an element that matches a selector. For example, to find the first paragraph tag (<p>) in the supplied HTML:
It is the responsibility of the application code to determine whether a request was successful from its perspective by inspecting the response within a load event handler.
Keep in mind that the browser considers any request that receives a complete response as successful, even if the response has a non-200 status code or represents an application error. Whether load or another event fires is determined by whether the HTTP request-response cycle loads a complete response. It does not consider the response's semantic meaning to the application.
The Event Object: Keyboard Events
Keyboard-related events also have special properties:
jQuery Object Methods: Property Name Syntax
Note that we quoted the font-size property name here, but didn't do that for color. Since font-size contains a hyphen that JavaScript tries to interpret as subtraction, we can't write font-size without quotes; the quotes prevent JavaScript from trying to process - as the subtraction operator. If this syntax annoys you, jQuery also accepts camel case property names instead. Whenever you have a CSS property that includes one or more hyphens, you can omit the hyphens and capitalize the next letter instead. For font-size, for example, you can use fontSize instead: Likewise, you can use backgroundColor instead of "background-color", and borderWidth instead of "border-width". You can use most CSS selectors as-is to access elements with jQuery, though you may need to "escape" some special characters. JQuery also provides a bunch of selectors that are unique to jQuery.
What are Identifiers in Paths?
Some of the paths used in API documentation or when discussing APIs include identifiers for specific resources. Take, for example, the path /products/42. The final segment of the path, 42, is a value that is used to identify a specific product. When referring to this path in the general sense and without a particular product in mind, it would be written /products/:id. The final segment, :id, is a placeholder for a value to be filled in later. Any value in a path that begins with a colon in this book should be considered a placeholder. Here are a few other examples: /api/:version/products/:id /api/v1/users/:id/profile
jQuery Object Methods: Chaining Method Calls
Suppose we want to set multiple CSS properties on the same element. We could write multiple calls to the method starting with the $content variable: $content.css('font-size', '18px'); $content.css('color', '#b00b00'); Repetitive code like this is tedious and error prone when working with more than a couple of properties. We can take advantage of the fact that most jQuery methods return an object that contains jQuery methods, which means you can chain calls together: $content.css('font-size', '18px').css('color', '#b00b00');
The jQuery Function: Collections
Suppose you want to act on all the list items on the page. As we mentioned earlier, the return value of jQuery is a collection. When we use an ID selector, the collection contains at most one element; with other selectors, it can be any size. The returned object is the same type of object as returned by $("#id"); both are collections.
When should you use event delegation?
The best approach is to start by binding event handlers directly to elements when a project is new and small. As the code grows in size and complexity, delegation may make sense to reduce the number of event handlers required. Keep in mind that you don't need to use document as the delegator: you can delegate events to any parent element of the elements you want to monitor. You can even have more than one element handling delegated events if it makes sense.
What are Private APIs?
They are intended only for internal use. These APIs are subject to change at any time. The Google search page uses a private API to get a list of search suggestions to display while a user is entering search terms. Sometimes it is possible to call private APIs, but in general, doing so is a bad idea for a variety of technical, ethical, and even potentially legal reasons.
True or false? When the error event for an XMLHttpRequest object fires, the loadend event still fires.
True, Yes, it still fires. The loadend event always fires after either an error, abort or load event.
True or False: Text nodes sometimes contain nothing but whitespace.
True. All text -- including whitespace -- in the original HTML appears in the DOM as a text node.
What are the two main events that fire during an XMLHttpRequest cycle? What about before the last event?
Two main events fire during an XMLHttpRequest cycle: one when it sends the request, and one when response loading ends. Before loadend triggers, another event will fire based on whether the request succeeded.
What basic code would you run when an event occurs on an XMLHttpRequest object?
We can use the same addEventListener method that we used for handling user or page events:
jQuery Object Methods: Getters and Setters
We often use the term setter method to refer to methods that set properties for an object. We also use the term getter method to refer to methods that retrieve the current values for a property. Some jQuery methods, including css, have both setter and getter forms: if you omit the last argument, the method acts as a getter; otherwise, it acts as a setter. Likewise, the width and height methods act as both getters and setters. To check the $content object's width, call width. To set it to half that width, we use the same method with the new width. Note that width and height return and use numeric values.
jQuery DOM Traversal: Looking Outwards from an inner Object using the closest method
What if we want to look further out than an immediate parent? This is when you would use the closest method. The closest method is very useful for finding the first ancestor element that meets the criteria passed to the method. If we want to find the first ul when starting at a li instead of selecting all possible ancestor uls, we could call it like this:
RESTful, Conventions, not Rules!
While there are many benefits for both providers and consumers in the use of RESTful APIs, pragmatic solutions often require favoring practical solutions, and that can mean deviating from conventions when there is reason to. It is important to remember that REST is a set of conventions and patterns for building APIs. It is more of a proven way to handle common situations than a workable solution for all possible problems. It is worth being as RESTful as possible, but there are times when it is not the best solution.
URL encoding also works with POST requests, but what must you include?
You must include a Content-Type header with a value of application/x-www-form-urlencoded when you do. Place the encoded name-value string in the request body.
In what sequence does the JavaScript runtime run the functions q, d, n, z, s, f, and g in the following code? setTimeout(( ) => { setTimeout(( ) => { q( ); }, 15); d( ); setTimeout(( ) => { n( ); }, 5); z( ); }, 10); setTimeout(( ) => { s( ); }, 20); setTimeout(( ) => { f( ); }); g( );
g, f, d, z, n, s, q Notice that g( ) still comes before f( ) even though the timeout duration defaults to 0. The reason for this behavior is that while the function can execute immediately already, it isn't until the next event cycle that it will execute. Another thing of note is that setTimeout's behavior can be unpredictable when the differences in duration are tiny. Consequently, the sequence you get may be different than the solutions.
jQuery Object Methods: Convenience Methods
jQuery also provides a variety of convenience methods directly attached to the jQuery object. If you need to check what type a variable is, you can use methods like $.isArray and $.isFunction. You can concatenate two arrays using $.merge, or make a new array with $.map. The most important method of the jQuery object is the $.ajax method, which lets you make AJAX requests in a much easier fashion than if you had to support multiple versions of Internet Explorer on your own.
Fill in the blank: It is the responsibility of application code to determine whether a request was successful from its perspective by inspecting the response within a __ event handler.
load
HTTP Responses have 3 main parts: what are they?
status code, headers, and body.
Determining the Type of a Node: Why does a Node's type matter?
A node's type determines what properties and methods it provides to a developer. Determining the element type is important so that you know what you can do with the node. It's easy to determine whether something is a Text node or an Element, but it's tricky to determine the exact Element type. Once you do know it, though, you can find the documentation on MDN.
What determines whether a request should use GET or POST as its HTTP method?
GET requests should only retrieve content from the server. They can generally be thought of as "read only" operations, however, there are some subtle exceptions to this rule. For example, consider a webpage that tracks how many times it is viewed. GET is still appropriate since the main content of the page doesn't change. POST requests involve changing values that are stored on the server. Most HTML forms that submit their values to the server will use POST. Search forms are a noticeable exception to this rule: they often use GET since they are not changing any data on the server, only viewing it.
What are the required components of an HTTP request? What are the additional optional components?
The HTTP method and the path are required, and form part of what is known as the start-line or request-line. As of HTTP 1.0, the HTTP version also forms part of the request-line. The Host header is a required component since HTTP 1.1. Parameters, all other headers, and message body are optional. Technically speaking the 'path' portion of the request-line is known as the 'request-URI', and incorporates the actual path to the resource and the optional parameters if present. In practice, most people simply refer to this part of the request-line as the 'path'.
What is an event listener aka event handler?
The code that the browser runs in response to the event. Event listeners are functions that the JavaScript runtime calls when a particular event occurs.
What are the four steps needed to setup an Event Listeners?
1.) Identify the event you need to handle. User actions, the page lifecycle, and more can fire events. 2.) Identify the element that will receive the event. Depending on the event, the object could be a button, an input field, or any other element on the page. 3.) Define a function to call when this event occurs. The function is passed a single argument, an Event object. For now, we won't be using this argument. We'll learn more about Events later. 4.) Register the function as an event listener. This step brings the first three together into a working system.
What is execution context in the realm of programming?
An abstract concept of an environment where the code is evaluated and executed.
All DOM Nodes have certain properties in common: nodeType
You can use this property to determine a node's type: it returns a number that matches a node type constant. Use the constant names instead of the numeric values to write clear code that checks the node type.
JS230 Quiz 2: Study the code below. Is the code asynchronous? function record(data) { // do something with `data` // statements omitted } let numbers = [1, 3, 5, 7]; numbers.forEach(record);
You can't determine whether code is asynchronous solely by looking at it. If it calls any functions, then you must be familiar with the behavior of each of those functions to determine whether any are asynchronous. In this example, we can't be certain since we aren't aware of how the record function works. If, for example, there is a setTimeout call somewhere in the code, then yes it is asynchronous.
Traversing Elements: textContent
You might wonder how you can access the Text nodes when using the above DOM properties since they don't include non-element nodes. The textContent property provides access to the text.
Preventing Propagation and Default Behaviors: Preventing Default Behaviors
Another useful method on Event objects is preventDefault. This method tells the browser that it shouldn't perform any actions that it might otherwise perform in response to a user's action. For instance, clicking a link typically loads a new page in the browser. preventDefault tells the browser not to do that. As described, the loading of the new page is prevented. Interestingly, though, an alert is still displayed. The takeaway here is that it is the "default behavior" — following through the new page in the href attribute — that is prevented and not the added event listener which contains the code for the alert.
What is the trade off of event delegation?
The listener may become complicated if it must handle multiple situations. Consider the following variation of the button clicker example that uses both buttons and links. We must treat them differently, depending on which was clicked: Even with merely two cases, our code is noticeably more complex, yet we only have to check the tag name and perform a simple action. In a large document, there may be many different situations; imagine the complexity that may result from even a dozen cases.
Element Attributes: classList
Working with the class attribute via className is inconvenient when elements have more than one class. This is common in some applications. Consider how we determine whether the button belongs to the btn class? Keep in mind that class may contain class names in any order. To make this determination, you must split className's value using spaces as a delimiter, then search the array to see whether it contains the string btn. You can do this, but it's tedious for something you will need to do fairly often. Modern browsers provide a better way with the classList property. classList references a special array-like DOMTokenList object that has these properties and methods:
Traversing Elements: caution with setting textContent
Be careful when setting textContent; doing so removes all child nodes from the element and replaces them with a text node that contains the value.
JS230 Quiz 1: Given the following HTML, what is the nodeValue of the p element? <body> <h1>Greetings!!</h1> <p><span>Hello</span>, world</p> </body>
Null. Element nodes don't have values.
An Asynchronous code example using setTimeout.
The undefined we see on the second line is the return value of line 9. About one second later, "World" appears, and two seconds later, the exclamation point appears. Examining the order in which the code runs doesn't tell the whole story, though. It's important to realize that there is a period between 3 and 4 and between 4 and 5 where nothing happens! None of your code runs during these gaps; instead, the JavaScript runtime keeps track of the timers created by setTimeout. No other code executes until the delay time elapses, then the callback function runs as expected.
JS230 Quiz 2: Check out the code and the web page below. Click around and observe what happens. How many event listeners does the page have?
There is only one. It may seem like there is more than one because of event delegation. It's also likely that you assume that the behavior added using the css :hover pseudo-class was instead added by using a mouseover event handler.
Creating and Moving DOM Nodes: Adding Nodes to the DOM: Element Node methods
These methods insert node before, after, or within an Element.
What are the downsides of working with events by adding handlers to elements that may be the source of events? What Technique can we use to solve this?
This approach results in event listeners attached to each element of interest on the page. It works fine in small applications, but there are downsides: - You can't add an event listener to an element until the DOM is ready, which means that you must wait until the DOMContentLoaded event fires. - You must add event handlers manually when you add new elements to the page after DOMContentLoaded fires. - Adding handlers to many elements can be slow, and can lead to complicated, difficult to maintain code. Imagine a page with a large spreadsheet-like grid with hundreds or thousands of cells; you must provide listeners for both keyboard and mouse events in every cell. A technique called event delegation provides a solution for these problems, but before we can learn how to use it, we first need to talk about capturing and bubbling.
JS230 Making HTTP Requests from JavaScript: Summary
- AJAX is a technique used to exchange data between a browser and a server without causing a page reload. - Modern browsers provide an API called the XMLHttpRequest to send AJAX requests. - Some modern applications rely exclusively on JavaScript and XMLHttpRequest to communicate with the server and build up the DOM. Such applications are called single page applications - XHR objects send asynchronous requests by default, meaning that the rest of the code continues to execute without waiting for the request to complete. - Important properties on an XHR object are: responseText, response, status, and statusText - The data sent along with requests, if any, must be serialized into a widely supported format. - The three request serialization formats in widespread use are: 1) query string/url encoding, 2) multi-part form data, 3) and JSON. - It's a good practice to send a Content-Type header with XHR. This helps the server parse the request data. - Three popular response formats are: 1) HTML, 2) JSON, 3) XML. - The single most popular serialization format currently in use is JSON. - To submit a form via XHR, an instance of FormData can be used to conveniently serialize the form into multi-part data format. - One useful property on an XHR object is responseType. It's particularly useful when the response is expected to be JSON. When its value is set to "json", the XHR object's response property gives us parsed JSON. - One major constraint on XHR is the browsers' same-origin policy that limits communication to the same domain, the same port, and the same protocol. Any attempt to communicate outside these limits result in a security error. - The standard solution for cross-origin restrictions is a W3C specification called Cross-Origin Resource sharing (CORS). CORS recommends using an Origin header on the request and an Access-Control-Allow-Origin header on the response for cross-origin communications.
When discussing APIs and how systems interact using them, you must distinguish between the system that the API belongs to and the external service (or user) that will use this API.
- An API provider is the system that provides an API for other parties to use. GitHub is the provider of the GitHub API, and Dropbox is the provider of the Dropbox API. - An API consumer is the system that uses the API to accomplish some work. When you check the weather on your phone, it is running a program that is consuming a weather API to retrieve forecast data.
Select all the statements that are true about data serialization: A Data serialization is the process of assigning unique ids for the data to be exchanged between client and server. B The objective of data serialization is to convert data to JSON format for use with AJAX. C Applications can use any data serialization format that both the client and server know how to read and write. D Serialization lets both the client and server transfer data in a format that preserves information without interfering with the communication protocol.
- Applications can use any data serialization format that both the client and server know how to read and write. - Serialization lets both the client and server transfer data in a format that preserves information without interfering with the communication protocol. A data serialization format describes a way for programs to convert data into a form that is more easily or efficiently stored or transferred. It is not about assigning ids to data and its scope is not limited to the JSON format.
Select the statements that are true about sending a request using the XMLHttpRequest object: A Setting headers using the XMLHttpRequest.setRequestHeader method must only be done once the XMLHttpRequest.open method has been called. B We need to at least pass the XMLHttpRequest.open method a value for the method argument; the value for the url argument defaults to the root path. C It is possible to make a synchronous request. D XMLHttpRequest.response and XMLHttpRequest.responseText are equivalent properties. The choice of one over the other is a matter of preference.
- Setting headers using the XMLHttpRequest.setRequestHeader method must only be done once the XMLHttpRequest.open method has been called. - It is possible to make a synchronous request. Choice B: Both the method and url parameters are required for the XMLHttpRequest.open method. There is no default value for the url parameter. Choice D: They are not equivalent. The XMLHttpRequest.response property's value is interpreted based on the value assigned to the XMLHttpRequest.reponseType property.
API Terms and Conditions: The data accessed via APIs carries with it ethical and legal responsibilities. Many API providers require developers to agree to terms and conditions of use before they are granted access. While these documents are usually written in legalese and can be a bit dense, it is important to understand what is and isn't allowed with respect to API data. In particular, keep in mind the following:
- What restrictions does the API place on your use of its data? For example, data from the Amazon Product Advertising API can not be used on mobile devices or TV set top boxes, nor can it be stored for more than 24 hours. - Is the API exposing any data that could be linked back to a person? Many social applications allow access to a user's personal information, and by accessing it, you are taking on the responsibility of keeping this information safe and secure. - Does the API have rate limits, and if so, what are they? Many APIs limit how many requests can be sent from a single user or application within a given time frame. Such restrictions can have an impact on the design of programs that interact with their APIs. API usage is often conditional on the acceptance of a set of terms set by the API provider.
Which of the following statements are true about making HTTP requests from JavaScript?
- When initiating HTTP requests from JavaScript, the developer must write code that initiates the request and handles the response. - HTTP requests from JavaScript are not dependent on the language used for the server-side code. - There is no requirement of intervals of 1 seconds. - The front-end application doesn't have to check the queue length on the server. If there are events queued, the server also doesn't inform the developer of when the request should be made again.
JS230 Quiz 2: Which of the following can be categorized as advantages of using event delegation?
- You can add an event listener to another element that handles an event on an element not yet present in the DOM. - You don't need to manually add event handlers when you add new elements to the page after the DOMContentLoaded event fires. - It makes code easier to maintain by reducing the number of event listeners that you need to add to a page.
What are Public APIs?
APIs that are intended for consumption outside the organization that provides them. Twitter, Facebook, Instagram, and many other social media sites provide public APIs that enable third-party programs to interact with their services.
Since a lot of web applications consist mainly of a user interface, the code within them has two main tasks, what are they?
1.) Set up the user interface and display it. 2.) Handle events resulting from user or browser actions. Since we're working in the browser, we typically achieve #1 with HTML, which lets us focus on #2, handling events.
Sending requests through XMLHttpRequest mainly involves the following steps, what are they?
1.) Create a new XMLHttpRequest object. 2.) Use the open method on the XHR object to specify the method and URL for the request. 3.) Use the setRequestHeader method on the XHR object to set headers you'd like to send with the request. Most of the headers will be added by the browser automatically. 4.) Use the send method on the XHR object to trigger the whole action and on POST request we can also pass serialized data as an argument. 5.) Attach an event handler for the load event to the XHR object to handle the response. 6.) Attach an event handler for the error event to the XHR object to handle any connection errors. This is not required but it's a good practice.
What is considered a RESTful design?
A design in which any action a user needs to make can be accomplished using CRUD operations on one or many resources. It can take a while to get used to thinking in a resource-oriented way since translating verb-oriented functionality (deposit $100 into this account) into noun- or resource-oriented actions (create a new transaction with an amount of $100 for this account) needs a change of perspective.
What are data serialization formats?
A format that describes a way for programs to convert data into a form which is more easily or efficiently stored or transferred. The stored or transferred data can then be converted back into the original data at any time by the original program or any other program that can understand its format. It provides a common way for systems to pass data to each other, with a guarantee that each system will be able to understand the data.
What is a call stack? (Not to be confused with stack and heap)
A stack with a LIFO (Last in, First out) structure, which is used to store all the execution context created during the code execution. JavaScript for example, has a single call stack because it's a single-threaded programming language. The call stack has a LIFO structure which means that the items can be added or removed from the top of the stack only. The picture shows how the call stack would be for the below code: const second = ( ) => { console.log('Hello there!'); } const first = ( ) => { console.log('Hi there!'); second( ); console.log('The End'); } first( );
Given that the current URL is http://www.thesite.com/data, requests to which of the following URLs will not be considered a cross-origin request? A http://www.thesite.com:5000/data B http://www.asite.com/data C https://www.thesite.com/data D None of the other choices
All URLs will be considered a cross-origin request. Choice A: Different port Choice B: Different host Choice C: Different scheme/protocol
What are Single Page Applications?
As client-side software development has become more involved, it has become increasingly common to make HTTP requests outside the main HTML page load. Some modern applications fetch data in a serialized format and create the DOM entirely from JavaScript running in a client's browser. We call these applications single page applications since they often run entirely within a single HTML page. Instead of fetching bits of HTML generated by a server, this model does all interactions by passing data to and from the server, often encoded as JSON.
What is the jQuery function?
At its core, jQuery is a function that wraps a collection of DOM elements and some convenience methods into an object. You can call the function to select the elements you need to process, and manipulate the object or its elements with methods built into the object. Internally, it is a function that works with an argument that you pass to it. - If the argument is a string or a DOM element, it wraps a collection of jQuery objects and returns them. - If the argument is a function, jQuery uses that function as a callback when the document is ready. While you can use the name jQuery when calling jQuery, it's common practice to use the alias $ instead.
What is a HTMLCollection or NodeList?
Both types are array-like objects, which means they are containers for other objects indexed by non-negative integers. Since these are not JavaScript arrays, they do not support forEach or other array methods. (NodeList on some browsers do support forEach, but not on all browsers; HTMLCollection provides no support for forEach.) To loop through the elements returned by these methods, use a for loop or convert the object into an array and then use the higher-order array functions. HTMLCollection and NodeList have differences, but they aren't important right now. All you must know is that document.getElementsByTagName returns one in some browsers and the other in other browsers.
Even if corresponding tags like HEAD and BODY don't appear in our HTML, what will the browser do?
Browsers insert missing elements like this since a fundamental tenet of the web is permissiveness; they always do their best to display HTML even when it has errors. The below code doesn't have HEAD or BODY tags: <html> <h1>Hello, world!</h1> <p>This is a small <em>web page</em>.</p> </html>
User Events (Most Commonly used List)
Building an interactive web application means responding to user actions. Depending on the input device, the application, and the user, your application may need to detect and react to more than a dozen different user-initiated events. Keep in mind that an event's type determines the kind of code it makes sense to run within an event handler, but registering and triggering events is the same for all.
Cross-Domain XMLHttpRequests with CORS: Cross-Origin requests with XHR
By default, an XHR object can't send cross-origin requests because of the aforementioned security problems. All browsers implement a security feature called the same-origin policy. It prevents XMLHttpRequest from making cross-domain requests. The application can request resources from the origin domain, but a request from any other domain causes an error.
CRUD and RESTful APIs
CRUD is an acronym that is used to describe the four actions that can be taken upon resources: Create, Read, Update, Delete. RESTful APIs consist of CRUD actions on a resource. RESTful APIs will model most functionality by matching one of these operations to the appropriate resource. By limiting actions to CRUD, REST requires thinking in a resource-oriented way.
jQuery Object Methods: Object Argument
Chaining method calls is easier to write, but it's still tedious. As with most jQuery methods, there are multiple ways to call css. One intriguing alternative uses an Object with key/value pairs that match up with the CSS property/value pairs you want to give the element, which lets you set any number of CSS property/value pairs at once. Thus, we can rewrite our code like this: $content.css({ 'font-size': '18px', color: '#b00b00' });
JS230 Quiz 2: Which of the following is not a valid syntax for adding an event listener.
Choice B is not valid syntax because onclick is not a method. To use it to add an event listener to an element, you must assign it a function like so: let button = document.querySelector('button'); button.onclick = event => console.log('Hello world!'); Choice D is not valid syntax. .on is a jQuery method and it won't work with the document object by default. We'll cover this method in the jQuery lessons.
Traversing Nodes in the DOM: Parent and Child Nodes.
DOM nodes connect with other DOM nodes via a set of properties that point from one node to another with defined relationships. For example, the childNodes property returns a collection of the nodes directly beneath a given node. Each element in the returned collection has a parentNode property that points back to the original node. The following diagram depicts how the parent/child properties map out the inter-nodal relationships:
Determining the Type of a Node: Nodes and Elements
DOM objects come in different types: Nodes, Elements, Text, and more. The Element type is further broken down into dozens of subtypes. Trying to determine the exact object type can be confusing. Here's what you need to know: - All DOM objects are Nodes. - All DOM objects have a type that inherits from Node, which means they all have properties and methods they inherit from Node. - The most common DOM object types you will use are Element and Text. Keep in mind that Elements include more specific, specialized Element types. For example, the DOM node that represents a <p> HTML tag has type HTMLParagraphElement, while the Element that represents a <div> tag is HTMLDivElement.
What is CORS?
Cross-Origin Resource Sharing is a W3C specification that defines how the browser and server must communicate when accessing resources across origins. The idea behind CORS is to let the two systems know enough about each other to determine whether the response should succeed or fail. Applications use custom HTTP request and response headers to implement this mechanism. According to the specification, every XMLHttpRequest sent by the browser must have an Origin header that contains the origin of the requesting page. The server uses this header to determine whether it should send a corresponding header in the response. The browser automatically adds the Origin header as part of an XHR. The Cross-Origin Resource Sharing specification fulfills the need for legitimate cross-origin requests. It gives us a standard way to access resources from different origins without the security problems associated with cross-origin requests. For example, if we send an XHR from a page hosted at http://localhost:8080, the browser adds the following request header: It's important to note that even if the server sends the correct response, but without the Access-Control-Allow-Origin header with the appropriate value, the browser will raise an error and not let the script access the response.
Traversing Nodes in the DOM: We don't use Arrays when walking the tree in the DOM. Instead, we use DOM nodes.
Each "smaller" argument is a child of the current node. Here is some code that does this:
Traversing Elements: Using a list of just element nodes, ignoring the text nodes in between.
Earlier, we looked at some properties that you can use to traverse DOM nodes. These properties often don't give you what you want, though; you probably want a list of element nodes without the Text and other nodes mixed in. You can simplify your code if you can start with a list of element nodes alone, and don't have to ignore everything else. Another set of DOM properties provides the functionality you need; you can find them in the element nodes. Most browsers include these elements in document, which has type Document. Internet Explorer does not, though; it provides them in document.body instead. You can use document.body with them all and get the expected results.
Element Attributes: style
Element nodes also have a style attribute that has some special behavior. The style attribute on an Element references a CSSStyleDeclaration Object. You can use the style attribute to alter any CSS property. For example, you can change the color of a heading to red. To remove a CSS property, set the property to null with the style property. When a CSS property's name contains dashes, you must use a camelCased version of the name to access that property. For example, to set a value for the line-height attribute, you assign a value to the lineHeight property. Most applications don't use the style property often; it's easier and more manageable to use classes in your stylesheet to alter the characteristics of your elements. You can add or remove CSS class names to or from any DOM Element.
What is event delegation?
Event delegation takes advantage of event propagation behavior and allows us to attach a single event listener, to a parent element, that will fire for all descendants matching a selector, whether those descendants exist now or are added in the future. * a simple technique by which you add a single event handler to a parent element in order to avoid having to add event handlers to multiple child elements * allows you to utilize event bubbling It takes advantage of event propagation to address these problems. Instead of adding listeners to every element you're watching, you can add a single handler to any of their parents. The listener, in turn, performs the required actions for each element.
What APIs Can Do: Enabling Automation
HatCo sweepstakes example. APIs allow users of a service to make use of it in new and useful ways. APIs provide an "escape hatch" enabling service users to customize the software's behavior or integrate it into other systems if required.
True or False: there is a direct one-to-one mapping between the tags that appear in an HTML file and the nodes in the DOM.
False. The browser may insert nodes that don't appear in the HTML due to invalid markup or the omission of optional tags. Text, including whitespace, also creates nodes that don't map to tags.
JS230 Quiz 2: True or False: When an event is triggered, it only goes through either the capturing or bubbling phase and this is determined by the value passed to the useCapture argument of the addEventListener method.
False. useCapture determines whether the event handler gets called during the bubbling or capturing phase. It does not determine which phase an event will go through.
When sending JSON via XHR, how do you go about serializing the data to JSON and Setting the Content-Type Header?
First, we must update the code to create a valid JSON string. We create a simple javascript object and use JSON.stringify(obj) to finish serializing. The second step is to set the Content-Type request header to application/json; charset=utf-8, which tells the server to expect JSON data. It's up to the server to do the right thing here, and not all will change their behavior based on the value of this header, but many APIs require that you set this value accurately; it's a good habit.
Web APIs are based on the same technologies that allow websites, web browsers, and web servers to work: HTTP.
HTTP, or Hypertext Transfer Protocol, describes how a client program (such as a web browser) interacts with servers. These interactions are based on a request-response pattern, where the client asks the server for something it wants (the request) and the server then sends something back (the response.) The web, as complicated as it can seem, is almost entirely built on top of this model of sequential requests and responses. APIs work in basically the same way, only instead of a human making requests through a web browser, API requests are usually made from one computer program to another. As a developer, you can call APIs from your own programs. This can enable your programs to do all kinds of things that would be difficult or impossible to do by themselves.
What is the impact that the preventDefault method has when there are nested elements listening for the same event?
Here are some things that we can observe from this example: 1.) The default behavior isn't for the element that the event listener is attached to, but rather for the event object; the anchor element's "click" event listener didn't have a preventDefault but a new page wasn't loaded. 2.) The browser waits for the event object to go through the propagation phases (capturing and bubbling) before it performs the default action of the event. If there's an event handler with a preventDefault call somewhere in the propagation path, the default behavior is skipped.
JS230 Quiz 1: Given the HTML below, identify which of the following will work as a starting point to get to the input element for the email. <!doctype html> <html> <head> <title>Newsletter Signup</title> </head> <body> <!-- A short comment --> <h1>Newsletter Signup</h1> <p class="intro"> To receive our weekly emails, enter your email address below. <a id="simple" href="info.html">Get more info</a> </p> <div class="form"> <form> <label> Enter your email: <input name="email" placeholder="[email protected]" /> </label> <p class="controls"> <button id="cancelButton">Cancel</button> <button type="submit" id="submitButton">Subscribe</button> </p> </form> </div> </body> </html>
Here's the code for each choice to get to the input element for the email: A: document.querySelector('[name="email"]'); B: document.head.nextElementSibling.querySelector('[name="email"]'); C: document.body.lastChild.parentNode.querySelector('[name="email"]'); D: document.body.childNodes[7].querySelector('[name="email"]'); Notice that as long as the return value is a node/element, we can traverse to the target node/element. The key takeaway here is that you can traverse the DOM in any direction.
Traversing Nodes in the DOM: What's going on here with the recurseAndLog function?
If you're new to recursion, this result probably seems confusing and mysterious, so let's add an extra console.log statement to observe the values of array at the beginning of each recursion. This output sheds some light on how recursive functions work for traversing collections: they do a bit of work then make the next call with a smaller version of the collection. In recurseAndLog, the argument is an Array, and each call to the function passes an Array with one less element. Each recursive call logs the first character of the array, then calls the function with that element removed. This process repeats until there's nothing left to do. If you feel that you're not grasping this concept yet, don't worry. For now, all you need to know is that a recursive function: - returns to the previous level of recursion when it's gone as far as it can. - performs a bit of processing. - calls itself with a "smaller" argument.
Example: Loading HTML via XHR
In this assignment, we've learned two important concepts: 1.) We can use an XMLHttpRequest object to fetch content and insert it in an existing web page without a full page reload. 2.) We can attach event listeners to content embedded in the page to circumvent the browser's default behavior and create custom interactions.
JS230 JavaScript Libraries: Summary
In this lesson, we explored the concept of using JavaScript libraries as part of the development process. The key take-away here shouldn't be remembering the specific functions and methods that those libraries provide, but instead to have a high level understanding of what these libraries can do and the role that they can play within your front-end development workflow. - Use documentation efficiently to ramp up quickly on a new library or API when you need to use it for a particular project. - Use Developer Tools built in to the browser as part of your work-flow to test and debug your front-end code. - At its core, jQuery is a function that wraps a collection of DOM elements and some convenience methods into an object. - jQuery provides methods for many aspects of front-end development, such as interacting with the DOM, managing browser events, and making Ajax calls. - Handlebars is a minimal templating library which allows you to easily add and update sections of a web page. - The Fetch API and jQuery's ajax() are alternatives to XMLHttpRequest for making Ajax calls. At a high level they all do the same thing: make a HTTP request and then process the response once it is received.
jQuery DOM Traversal: Looking Inwards from an outer Object
Instead of going outward to find the uls, let's now start at the outermost ul and find all of the list items. One extremely useful method is the find method. You can call it on an existing jQuery object to traverse to one of its child elements using another CSS-like selector. Now we'd like to collect only the immediate children lis from the navigation ul. We can use the children method either with or without a selector, just like the parent method. Since our HTML is well-formed, we know that the only elements that will be immediate children will be lis and we won't have to pass in a selector.
Traversing Nodes in the DOM: Walking the Tree.
Is a term that describes the process of visiting every node that has a child, grandchild, etc. relationship with a given node, and doing something with each of them. We use a recursive function to do this. We haven't looked at recursion in JavaScript yet, and a full exploration is a bit beyond our current needs. For now, all you must know is that a recursive function is a function that calls itself.
HTTP Request Side Effects
It is always worth considering what effects the requests you make could be having on the remote system. All of the requests we've made to the web store server have been GET requests. GET requests, by definition, should not alter the resources they are performed against. There can, however, be other side effects. One example of this is a simple hit counter that increments each time a page is loaded. As a result, even though making GET requests is generally considered "safe" in that no data is being explicitly altered on the remote end
What is an event in programming?
It is an object that represents some occurrence; it contains information about what happened and where it happened. The browser can trigger events as the page loads, when the user interacts with the page, and when the browser performs some action required by the program.
What is an internet resource?
It is the representation of some grouping of data. A resource can be anything an API user needs to interact with. Blog software might expose posts, sections, tags, and comments as resources in its API, and it might allow users to create or edit any of those resources. A bank's API might provide access to accounts and transactions but only allow viewing transactions. Every resource in a web API must have a unique URL that can be used to identify and access it.the representation of some grouping of data. A resource can be anything an API user needs to interact with. Blog software might expose posts, sections, tags, and comments as resources in its API, and it might allow users to create or edit any of those resources. A bank's API might provide access to accounts and transactions but only allow viewing transactions. Every resource in a web API must have a unique URL that can be used to identify and access it.
What is an API, or Application Programming Interface?
It provides a way for computer systems to interact with each other. There are many types of APIs. Every programming language has a built-in API that is used to write programs. Mobile devices provide APIs to provide access to location or other sensor data, such as the device's GPS location or the orientation of the device. Operating systems themselves have APIs used by programs to open files, access memory, and draw text on the screen. While the types of uses for APIs are vast, the one thing all APIs have in common is providing functionality for use by another program.
What does the Accept Header of a HTTP request do?
It specifies what media types the client will accept in response to this request. */* means that the client will accept any media type in a request. The web store server returns JSON by default, so requests like the previous one would probably be OK to use. However, it is better to be in the habit of crafting more explicit requests.
Request Serialization Formats: JSON Serialization We'll use the following data to illustrate the differences: { "title": "Do Androids Dream of Electric Sheep?", "year": 1968 }
JSON (JavaScript Object Notation) is a popular data serialization format used by APIs. It's used by programs written in different languages to exchange arrays, objects, strings, numbers, and boolean values over the network. JSON does not provide native support for complex data types like dates and times. Instead, you must represent such values in a format that both the client and server understand; strings, numbers, and objects work well for this in most cases. A GET request can return JSON, but you must use POST to send JSON data to the server. Here we make our request using JSON format: Note that the Content-Type header has a value of application/json; charset=utf-8. This is required if you want to use JSON as the request serialization format. The server may not parse the request correctly if this header has the wrong value.
Go over the following code and select the statements that are true about it. You may assume that the URL is valid and that the server responds accordingly. let request = new XMLHttpRequest(); request.open('GET', 'http://foo.bar/api/data'); request.responseType = 'json'; request.addEventListener('load', event => { let data = JSON.parse(request.response); // do something with data }); request.send();
JSON.parse is not necessary and leads to an error. Choice B: The code results in an error. However, parsing request.responseText still results in an error since the value of responseType is set to json. The value of responseText is only accessible if the responseType is '' or 'text' Choice D: The code results in an error because the value passed to JSON.parse is not a valid value. JSON.parse is expecting a string but it receives an object. It is an object already because we set the responseType to JSON and as such the browser handles the parsing for us.
What is Rate Limiting?
Just as it is easy to write a simple loop in a programming language that does something thousands of times in just a few seconds, it is just as easy to make thousands of requests to a remote API in an equally short period of time. Since many APIs have to support many users at the same time, the possibility of there being too many requests to handle becomes extremely likely. Most APIs address these by enforcing rate limiting. This means that each API consumer is allotted a certain number of requests within a specified amount of time. Any requests made beyond these limits are sent an error response and not processed further. The status code of responses to rate limited requests varies by service, but it is often 403 Forbidden. When encountering these rate-limiting errors, it is often enough to simply perform the request less often. If the same request is being made over and over, the response can be stored locally to reduce the number of requests being made.
Element Attributes: Getting and Setting Attributes
Let's look again at a simple paragraph element: > let p = document.querySelector('p'); > p; = <p class="intro" id="simple">...</p> We can access the attributes of an Element using these methods: When using setAttribute please take note of this warning from MDN: Using setAttribute to modify certain attributes, most notably value in XUL, works inconsistently, as the attribute specifies the default value. To access or modify the current values, you should use the properties. For example, use Element.value instead of Element.setAttribute.
What is the raw text of the HTTP request the example below will send to the server? let request = new XMLHttpRequest( ); request.open('POST', 'https://ls-230-book-catalog.herokuapp.com/books'); request.setRequestHeader('Content-Type', 'application/json; charset=utf-8'); let data = { title: 'Eloquent JavaScript', author: 'Marijn Haverbeke' }; let json = JSON.stringify(data); request.send(json);
POST /books HTTP/1.1 Host: ls-230-book-catalog.herokuapp.com Content-Type: application/json; charset=utf-8 Accept: */* {"title": "Eloquent JavaScript", "author": "Marijn Haverbeke"}
Request Serialization Formats: Multipart Forms We'll use the following data to illustrate the differences: { "title": "Do Androids Dream of Electric Sheep?", "year": 1968 }
POST requests use multipart form formats for forms that include file uploads or that use FormData objects to collect data. This format isn't strictly an encoding format since we don't encode anything. Instead, we place each name-value pair in a separate section of the request body. A boundary delimiter defined by the Content-Type request header separates each part: Content-Type: multipart/form-data; boundary=----WebKitFormBoundarywDbHM6i57QWyAWro Note that the final boundary delimiter has an extra -- at the end; these characters mark the end of the multipart content.
Request Serialization Formats: Query String / URL Encoding We'll use the following data to illustrate the differences: { "title": "Do Androids Dream of Electric Sheep?", "year": 1968 }
Many web applications use a serialization format that you've already seen and used: URL encoding for query strings. A query string consists of one or more name=value pairs separated by the & character. This format is easy to use and understand, though the presence of non-alphanumeric characters in the names or values can complicate matters. You must encode those characters. For example, you can encode spaces in a query string as either %20 or +. JavaScript provides a built-in function, encodeURIComponent, that lets you encode a name or value using this format. You can then combine the name-value pairs with =, and combine the resulting strings with &. Name-value pairs can be used both as part of a URL and in the body of a POST request.
What is a Media Type?
Media types describe the format of a response's body. Media types are represented in an HTTP response's Content-Type header, and as a result, are sometimes referred to as content types. In the same way that humans have developed shared languages to facilitate communication, the internet has given rise to a set of shared markup languages and data formats for transferring information between computers. HTML is one of many different media types (also called content types or sometimes MIME types) supported by modern web browsers. It is represented in an HTTP response as the Content-Type header as text/html: This tells the browser to interpret the content as HTML and render it graphically on the screen.
The Event Object: Mouse Events
Most events have properties specific to their type. For example, here are some of the properties available for mouse events: Both clientX and clientY return values relative to the visible area of the page: the number of pixels from the upper-left corner of the browser's viewport.
The Browser Object Model (BOM)
Most of this lesson focuses on the Document Object Model, the tree of objects that represents the displayed document. You can access other components of the browser with JavaScript that go beyond the page contents. These components include: - The windows used to display web pages - The browser's history - Sensors, including location These components comprise the Browser Object Model or BOM. We won't explore these topics in depth now, but you should know about them. They're a step away with JavaScript.
JS230 Quiz 1: If we modify the HTML from the previous question to the following: <div> Hello, <em>world!</em> </div> Will the result still be the same?
No. The div element has more than one child and consequently, the nodeValue of the firstChild is the text between the opening <div> tag and the opening <em> tag. On the other hand, the value for textContent of the div element is the concatenation of the textContent property value of every child node.
According to the pictured code, describe the relationship of nested elements to events.
Notice that an alert box displays the id whenever you click any element starting from the div#elem2 element all the way down to the innermost, div#elem4, element. The critical thing to note here is that even though we added an event listener to a single element, we can interact with three different elements. Contrast this to the first scenario where we can just interact with one element. If you play around with the code and add the event listener to the outermost, div#elem1, element there will be four elements to interact with. The number of elements you can interact with is equal to the element (the div#elem1 element) the event listener was added to plus the number of its "nested" inner elements (div#elem2, div#elem3 and div#elem4 elements). This begs the question, are my event listeners increased by the number of nested elements?
jQuery Object Methods: css method
Once you obtain an object from jQuery, you can perform a variety of tasks with it. You can, for example, change the font-size for all of the elements represented by the object with the css method: Note that you must pass a string value for the second argument of css and that you must include the measurement units when appropriate.
What APIs Can Do: Sharing Data
Perhaps the most common use case for web APIs is simply sharing data between systems. Consider a web application for creating birthday cards. Instead of requiring a user to enter the names and birthdays for each of their friends, the application could use an API provided by Facebook to fetch data about a user's friends automatically. At a certain level, all APIs are used to transfer data between systems. This basic capability offers many benefits to application developers and users alike. An extremely common case would be providing data to a mobile application that needs to access data from a web-based service. APIs break down the walls between systems, allowing them to share data.
Example: Sending JSON via XHR
Sending JSON data to the server is similar to submitting a form. You use the same three steps, with a couple of adjustments: 1.) Serialize the data into valid JSON. 2.) Send the request using XMLHttpRequest with a Content-Type: application/json; charset=utf-8 header. 3.) Handle the response.
What is XML? (or extensible markup language)
Shares common heritage with HTML: they are both based on an earlier and similar type of markup, SGML. XML is generally stricter than HTML and doesn't handle missing tags or improper nesting. It was fairly common to see XML used with APIs in the past, and while some services continue to support XML, JSON has become much more common. Here is one way to represent an address in XML:
All DOM Nodes have certain properties in common: textContent
Represents the textual content of all the nodes inside the Element. You can think of it as the nodeValue for all the Element's child nodes concatenated into a single String. For example, if we access the paragraph's textContent property, it contains the content of the Text nodes directly inside the tag as well as the text within the a Node that the p Node contains. We've seen that nodeValue references the textual content of the Node, but Elements don't have any textual content, so the nodeValue for Elements is null. We can use a different property when we need the text within an Element: textContent. textContent joins the nodeValues of all child Text Nodes together, including the empty Nodes, which leads to excess whitespace. You can deal with the excess whitespace using the usual String and RegExp methods.
What is the name of the policy that prevents XMLHttpRequest from making cross-domain requests?
Same origin policy
What is The DOM Ready Callback?
Since most of jQuery acts on DOM elements, we must wait for the page to load before we execute our code. jQuery has that covered as well. Meet the DOM ready callback: $(document).ready(function( ) { // DOM loaded and ready, referenced image on img tags are not ready }); The callback function we pass to ready executes after the document, and its dependencies, finish loading. Note, though, that ready doesn't wait for the browser to load images included via <img> tags. In some cases, you must delay execution until the window finishes loading: $(window).load(function( ) { // DOM loaded and ready, referenced image on img tags loaded and ready }); Typically, you can wait for the DOM ready event before running your code. If it uses the natural image dimensions, though, you must wait for the window load event instead. There's an even shorter way to write a DOM ready callback. You can skip traversing the document and binding to its ready event by passing a callback function directly to the jQuery function, $( ): $(function() { // DOM is now loaded });
What is a Live Collection?
Some DOM-querying methods return collections that are called live collections. Live collections have a special behavior in that they automatically update to reflect changes in the DOM, hence the term "live". Methods like document.getElementsByClassName and document.getElementsByTagName, when they return an HTMLCollection, return it in the form of a live collection. It is important to take note of this because it can lead to unexpected behavior, especially when you iterate over it or use the return value.
jQuery DOM Traversal: Finding Sibling Elements using nextAll, prevAll and siblings methods
Sometimes, however, you may want to do something like grab all of the sibling elements that come after the current one and perform some action on them. The nextAll method will return all siblings after, with an optional selector passed in. There's a complementary method called prevAll that goes in the opposite direction. And if you needed all the siblings, rather than grabbing the parent and then getting all its children, you could simply use siblings with an optional selector. The next( ) and prev( ) methods get a single sibling element, either immediately after or immediately preceding the current one.
What are the required components of an HTTP response? What are the additional optional components?
Status code is required. Headers and body are optional.
What is JSON (or JavaScript Object Notation)?
perhaps the most popular data serialization format used by web APIs today. The syntax JSON uses is based on the way object literals are written in JavaScript, the ubiquitous scripting language of the web. While JSON's popularity is partially due to being based on existing web technologies, a distinction it shares with XML, it is also the result of JSON being a simpler and less ambiguous format. A simple JSON document is used to represent key and value pairs. Here is one way to represent a US address as JSON:
As web applications become more interactive and their interfaces more complex, the need to reload an entire HTML page becomes a limiting factor. Developers need different methods to work around it; they need a way to replace only part of the page. Describe the new technique used to work around this dilemma.
That new technique is AJAX: Asynchronous JavaScript And XML. AJAX gained popularity for its ability to fetch data, typically HTML or XML, and update parts of a page. When you hear someone mention "an AJAX request" or "via AJAX," they refer to an HTTP request from a web browser that does not perform a full page load. There are two things worth noting about how this interaction differs from typical page navigation where a user clicks a link, the browser sends the HTTP request to the server, the server returns entire HTML page, then the browser parses and displays new page: - The web browser doesn't make an automatic HTTP request; instead, JavaScript code initiates it, typically from an event listener. - When the browser receives a response, JavaScript code takes the response's body and updates the page as needed. To summarize: when requesting a resource using JavaScript, the developer must write code that initiates the request and handles the response.
The DOM can also be seen as a hierarchy of nodes.
The DOM is a hierarchical tree structure of nodes. Try to imagine what the DOM created for the above HTML code looks like. <html> <h1>Hello, world!</h1> <p>This is a small <em>web page</em>.</p> </html> You might come up with something like this:
How can you change the phase in which the event listener gets called/fired?
The actual event listener, though, gets called/fired in only one phase. By default the listener is set to fire during the "bubbling" phase. To set it to listen on the "capturing phase" you can use the third optional, argument, for the addEventListener method, useCapture, and set it to true. elem1.addEventListener('click', callbackFunction, true);
What must JavaScript applications that run in a web browser do with their data when communicating with remote systems?
The app must serialize data when communicating with remote systems. Serialization lets both the client and server transfer data in a format that preserves information without interfering with the communication protocol. Applications can use any data serialization format that both the client and server know how to read and write.
Request Serialization Formats: Content-Type and charset
The charset is optional, but it's best practice to include it except when using multipart form format. Providing the charset ensures that the server interprets the data with the correct encoding. You can use charset=utf-8 in most cases, meaning that the data uses the UTF-8 character encoding.
Cross-Domain XMLHttpRequests with CORS: Cross-Origin Requests
The scheme, hostname, and port of a web page's URL define its origin. A cross-origin request occurs when the page tries to access a resource from a different origin. Let's consider the URL http://mysite.com/doc1. If the web page from this URL requests a resource from any of the following URLs, it will be considered a cross-origin request. https://mysite.com/doc1 (different scheme/protocol) http://mysite.com:4000/doc1 (different port) http://anothersite.com/doc1 (different host) A cross-origin request could be a request for an image, a JavaScript file, an XHR, or any other resource. The most important kind of cross-origin request for our purposes is a cross-domain request: a request from one domain (hostname) to another domain. Cross-domain requests in web browsers have security vulnerabilities that hackers can exploit to launch attacks. These attacks often lure a user into clicking a carefully crafted link that sends a request to an application with the user's login credentials.
What is the job of the event loop in regards to asynchronous code?
The job of the Event loop is to look into the call stack and determine if the call stack is empty or not. If the call stack is empty, it looks into the message queue to see if there's any pending callback waiting to be executed.
What APIs Can Do: Leverage Existing Services
The number of things a modern web application is expected to do is vast. Even fairly simple sites will need to process credit card payments, send emails, fetch information about books, or call cell phones and read messages to the recipient. While it is possible to write all of the code to perform these tasks oneself, it usually doesn't make sense to, especially for smaller companies with basic needs. APIs enable application developers to build their applications on top of a variety of other specialized systems, allowing them to focus on their actual objectives and not worry about all the complexities of every part of the system. In a way, it's like hiring a team of specialists for a construction project. While it would be possible to do everything, it makes a lot more sense to delegate certain responsibilities to a specialist. A project will have better results if it is built by a plumber, an electrician, and a carpenter than if it was all done by a single person. Plus, the team effort will likely result in a higher quality product in less time. Many modern web applications provide an API that allows developers to integrate their own code with these applications, taking advantage of the services' functionality in their own apps.
Determining the Type of a Node: How do you actually determine the node type from an interactive console sessions using the browser's developer tools?
The technique most useful on the console uses the toString method or the String constructor on the node; you can read the name from the display: > p.toString( ); = "[object HTMLParagraphElement]" For most nodes, the return value of toString and String is the node type's name, but not all node types behave so well. This inconsistency is bothersome, of course. As a workaround, you can call the node's constructor property; it references a function that creates Objects of the appropriate Element type. The value is browser-dependent, though, which adds some clumsiness when using it. Regardless of which browser you use, the named Function is the Function that created the node, so it's easy to determine the node type. Note that some older browsers append a trailing Constructor to the Function name -- you should ignore it if present.
What is REST in regards to API development?
The term REST is often used to describe a set of conventions for how to build APIs. REST stands for representational state transfer. - representational refers to how a representation of a resource is being transferred, and not the resource itself. - state transfer refers to how HTTP is a stateless protocol. This means that servers don't know anything at all about the clients, and that everything the server needs to process the request (the state) is included in the request itself. A good way to think about REST is as a way to define everything you might want to do with two values, what and how: - What: Which resource is being acted upon? - How: How are we changing / interacting with the resource? Nearly all interactions with a RESTful API can be defined in this way.
What is the value of this within the handler when using a function expression?
The value of this within the handler when using a function expression is the element that the listener was added to — currentTarget. As such, the following code are equivalent:
How to know if a URL is for a collection or a resource?
There are a few ways to know what kind of resource a URL represents by looking closely at its path. Keep in mind that when in doubt, it is best to reference the API's official documentation. Sometimes there won't be documentation, though, and there are a few clues that can be a sign of what kind of resource a URL is for. Signs a URL is for a collection: - The path ends in a plural word, such as example.com/products - The response body contains multiple elements Signs a URL is for a single element: - The path ends in a plural word, a slash, and then what could be an identifier (which could be numeric or alphabetic) - The response body contains a single element
jQuery DOM Traversal: Looking Outwards from an inner Object using the parent method
There are two methods that you'll use for this depending on the situation. The first, parent, is used with and without a selector.
JS230 Quiz 1: Suppose we ran the following code on the DOM created with the HTML from question 8. The HTML equivalent of the resulting DOM will have a problem. What's that problem? let addIntroInfo = document.querySelector('.intro').cloneNode(true); let addIntroInfoLink = addIntroInfo.querySelector('a'); addIntroInfo.firstChild.nodeValue = 'We also have previous new letters.'; addIntroInfoLink.textContent = 'Check them out here.'; addIntroInfoLink.href = 'newsletters.html'; document.body.insertBefore(addIntroInfo, document.querySelector('.form'));
There will be w3c validation warnings/errors because calling cloneNode on the element with a class of .intro has a child with an id attribute. Choice D would have been a correct statement if false was passed as an argument to cloneNode instead of true.
What is capturing and bubbling?
They are the phases that an event goes through after it initially fires. The event first gets dispatched to the global window object, then to the document object, all the way down to the target element, which is the element on which the event was originally fired. At this point, this dispatch process reverses and from the target element the event works its way through containing elements until it reaches the window object. Using the HTML from our scenario of "clicking on the div#elem4 element only once", this process looks like this: Note 1.) The diagram may suggest that there are many click events happening, but actually, there's just one click event. This one click event object moves through the capturing and bubbling phases and checks if there are any listeners for it on the DOM objects that it passes. Note 2.) The event gets dispatched to each element twice, once during the capturing phase and once during the bubbling phase. The actual event listener, though, gets called/fired in only one phase. By default the listener is set to fire during the "bubbling" phase. To set it to listen on the "capturing phase" you can use the third optional, argument, for the addEventListener method, useCapture, and set it to true. elem1.addEventListener('click', callbackFunction, true); // Notice the third argument. It's set to `true`. When it's set to true, the event listener will listen during the capturing phase. If not specified, `useCapture` defaults to `false` and the event listener listens during the bubbling phase. Note 3.) When event listeners fire on the target element it is also described as firing on the "target phase."
Consider a scenario where a user searches for Canada and types "Can" before pausing for a moment. Our application sends an XHR for the query "C", then for "Ca", and finally for "Can". However, when we think about it, only the "Can" result matters, which replaces the previous two responses. If the user types fast enough, he'll never see the first two responses (or he may see them in rapid succession). Making requests that you don't need is bad practice; it puts an undesirable strain on the server, which is a huge concern in a production environment. What is the solution to this problem?
Throttling provides a solution to this problem. What we would want to do is delay sending an XHR to the server for a short period, and not send it at all if we no longer need it. The technique waits for some specified time before sending a request to the server. If, in the interim, that request becomes irrelevant due to a newer request, we discard the original request and start a new delay period for the newer request. Many JS libraries provide this capability, often with a function named debounce. This function takes a callback and a delay in milliseconds as arguments and returns a new function that calls the callback after the specified delay elapses. The utility of debounce isn't limited to optimizing AJAX requests. It can optimize the calling frequency of any event handler that gets called too often. Examples include scrolling and mouse movements.
URL or URI?
URI, or uniform resource identifier, is a name used to identify a resource. The resources represented by URIs can be anywhere. URIs are like social security numbers which could be used to reference specific individuals. But if you needed to have a face to face conversation with a person, just knowing their social security number would do little to tell you where to find them. URL, or uniform resource locator, is the location where a resource can be found. URLs, on the other hand, are like street addresses. Given the street address of a person, it is possible to actually find and interact with that person. These identifiers also uniquely identify a resource, which means that a URL is a kind of URI. URLs also include how to access the resource. When it comes to deciding to use URI or URL, The thing to remember is this: if you are working with resources on the internet, just use URL.
Making a Request with XMLHttpRequest.
Use the XMLHttpRequest object to send a HTTP request with JavaScript. This object is part of the browser API, not the JavaScript language. To send a request, we must provide the same parameters we would use when sending an HTTP request from any other language or tool: a method, a host, and a path. Note that request.send is asynchronous, meaning that code execution continues without waiting for it to complete. You may sometimes see code where request.open receives a third argument, either true or false. This argument specifies whether the method should make a synchronous or asynchronous request. Since you should never make synchronous requests from JavaScript, most contemporary browsers deprecate them, which suggests that you should always use true as the third argument. Since the argument defaults to true, you can omit it from most code.
JS230 Quiz 1: Which of the following choices most accurately describes what "Walking the Tree" means?
Walking the tree is the process of visiting every node that has a child, grandchild, etc. relationship with a given node, and doing something with each of them.
Traversing Nodes in the DOM: Recursive Function
We haven't looked at recursion in JavaScript yet, and a full exploration is a bit beyond our current needs. For now, all you must know is that a recursive function is a function that calls itself. Let's look at a simple recursive function before we work with one on the DOM. We'll start with a non-recursive function that takes an array as an argument and logs each element in the Array to the console: Notice that this method has no loops of any kind. Converting a function to use recursion often means eliminating a loop. The lack of a loop, though, doesn't suggest that a function is recursive, nor must a recursive function have no loops. The main point is that recursion can replace a loop. recurseAndLog has the same behavior as the non-recursive iterateAndLog:
The Event Object
We learned how to create event handlers that execute when a particular event occurs. For instance, we can define a handler for click events like this: document.addEventListener('click', event => { // respond to the click }); If all we need to know is that a click occurred, then it's easy to add some code to the handler to do what we need to do. What if we need more information about the event, though? The argument passed to the event handler provides this extra information; it's an Event object that provides contextual information about the event.
What is the most powerful benefit of REST?
What is most powerful about REST is that by being a set of conventions, it is universal and applies just as well to any kind of resource. By following REST conventions, API designers have fewer decisions to make about how to build an API and API consumers have fewer questions to answer before using one. Fetching an object? It's probably a GET request to /things/:id. Creating a new resource? Use a POST to /things. The resource-centric nature of REST and limited set of CRUD actions limit the complexity for API providers and consumers alike.
Creating and Moving DOM Nodes: Removing Nodes
When you remove a node from the DOM, it becomes eligible for garbage collection unless you keep a reference to the node in a variable. You cannot access an object that is eligible for garbage collection, so it's no longer available to your program.
jQuery DOM Traversal: Looking Outwards from an inner Object, There is one very important difference in how the closest method works compared to parent
With parent, it never looks at the current element for consideration. With closest, it first looks at the current element to see if it is a match. That means that if we were to start with our $('p') collection and look for the .closest('p'), we'd get the same elements as what we already have in our collection. Be sure to keep this in mind when using closest to avoid any unwanted behavior.
Cross-Domain XMLHttpRequests with CORS: Cross-Origin Resource Sharing
You might ask how you can use all the APIs available for public consumption on web applications if cross-origin requests from XHR objects aren't allowed? Indeed, many applications do use APIs for weather information, stocks, sports scores, maps and all kinds of other services hosted at different domains. The answer is that they use the Cross-Origin Resource Sharing (CORS) mechanism to allow cross-origin access to resources.
Making a Request with XMLHttpRequest: An Overview of XMLHttpRequest Methods
You should become familiar with how to use the following XMLHttpRequest methods and properties.
Example: Loading JSON via XHR
You should take advantage of the responseType property on the request to tell the browser how to handle the data it receives. The valid values for responseType are: text, json, arraybuffer, blob, and document. In the example above, we would set responseType to json, which would let us simplify our code to the following: Setting responseType lets us avoid extra error-handling code that we may need in the JSON.parse example. We can avoid this boilerplate by setting responseType to json. request.response either contains a value, or it doesn't, and our code can check that condition.
HTTP Requests have 4 main parts: what are they?
a path, method, headers, and body.
What are the two types of resources involved in the use of RESTful APIs?
elements and collections: - Elements are the representation of a single resource, such as the first request above. Operations that involve a single resource are done in the context of that resource, and will use that resource's path. - Collections represent a grouping of elements of the same type. It is common for collection and element resources to have a parent-child relationship, where the collection is the "parent" and an element is a "child", although this is not always the case. Here is what could be the path to a collection of blog posts:
Element Attributes: Attribute Properties
getAttribute and setAttribute work for all attributes, but you can access some attributes another way. The DOM exposes these special attributes as properties of the Element: id, name, title, and value. You can fetch the value for one of these properties or set it to a new value using standard property access and assignment operations: Not every Element type has these properties: the name and value attributes, in particular, are invalid on most elements. The class attribute is similar, but uses the className property since class is a JavaScript reserved word:
When we speak of clients and servers in the context of APIs, what do we generally mean?
the server is generally going to be the API provider and the client will be the consumer (technically, a client is the side of a communication that initiates the connection.) As a result of this, the terms are sometimes used as if they were synonyms. As a result, it is best to stick to using provider and consumer when discussing APIs, as this makes the relationship of the computer to the API much clearer. It is best to prefer the terms provider and consumer over client and server.
JS230 Quiz 2: Select all statements that are true about the DOMContentLoaded event:
- Any JavaScript that needs to use the DOM must wait for this event to fire. Choice A: The event described in this statement is the load event. Choice B: This isn't true. So long as the DOM is loaded already, its node can be interacted with.
JS230 Quiz 1: Select all properties and methods that you can use to add a class to an element.
- Element.className - Element.setAttribute - Element.classList.add Choice A is not a valid property. Choice B and C works also but it isn't as straightforward as Choice D. Here's how to make it work for className:
JS230 The DOM: Summary
- The Document Object Model, or DOM, is an in-memory object representation of an HTML document. It provides a way to interact with a web page using JavaScript, which provides the functionality required to build modern interactive user experiences. - The DOM is a hierarchy of nodes. Each node can contain any number of child nodes. - There are different types of nodes. The types you should be familiar with are elements and text nodes. - The whitespace in an HTML document may result in empty text nodes in the DOM. - Useful properties of nodes include nodeName, nodeType, nodeValue, and textContent. - Nodes have properties that traverse the DOM tree: firstChild, lastChild, childNodes, nextSibling, previousSibling, and parentNode. - Element nodes have getAttribute, setAttribute, and hasAttribute methods to manipulate HTML attributes. - Elements have properties that let you read and alter the id, name, title, and value. - Elements let you read and change CSS classes and style properties via the classList and style properties. - document.getElementById(id) finds a single Element with the specified id. - document.getElementsByTagName(name) and document.getElementsByClassName(name) find any Elements with the specified tagName or class. - document.querySelector(selector) returns the first Element that matches a CSS selector. document.querySelectorAll(selector) is similar but returns all matching elements. - Elements have properties to traverse the DOM tree: firstElementChild, lastElementChild, children, nextElementSibling, and previousElementSibling. - You can create new DOM nodes with document.createElement(tagName) or document.createTextNode(text). - You can create a copy of a node with node.cloneNode(deepClone). - parent.appendChild(node), parent.insertBefore(node, targetNode), parent.replaceChild(node, targetNode), element.insertAdjacentElement(position, newElement), and element.insertAdjacentText(position, text) add nodes to the DOM. - node.remove( ) and parent.removeChild(node) remove nodes from the DOM.
Consider a web page with eight buttons. When the user clicks a button, we want something to happen; here, we'll update a div with a message that indicates the clicked button: This code waits for the DOM to finish loading and then loops through every button element on the page, and adds an event handler to each. This technique works fine, but it does have some drawbacks: what are they?
- We must wait for the DOM to finish loading before adding event handlers. It isn't hard to do this, but it might introduce timing problems if we have other code that also must wait before it runs. - Modern web pages often add new elements after the page finishes loading. Here, we're binding the event listeners to elements that already exist when the page finishes loading. Any elements added later, though, won't have those event handlers. Instead, the developer must explicitly add listeners to new Elements as the application adds them. - Attaching many listeners to a document has a cost in performance and memory. For our eight buttons, this overhead is negligible, but imagine a spreadsheet application with thousands of cells, each of which needs several event handlers. We now have to register thousands of listeners, which can cause the page to "freeze" while JavaScript creates them.
JS230 Event-Driven and Asynchronous Programming: Summary
1.) setTimeout(callback, delay) invokes a function after the specified number of milliseconds. 2.) setInterval(callback, delay) invokes a function repeatedly in intervals of some specified number of milliseconds. clearInterval clears the interval and prevents future invocations of the Function. 3.) An event is an object that represents some occurrence and contains a variety of information about what happened and where it happened. The browser triggers some events as it loads a page and when it accomplishes some actions directed by an application. The user also triggers events when he interacts with the page. 4.) Code that must access the DOM should be invoked after the DOMContentLoaded event fires on document. 5.) User events drive most user interfaces and can result from a user interacting with the keyboard, mouse, touchscreen, window or other devices. Examples of these user events are click, mouseover, keydown, and scroll. 6.) Event listeners are callbacks that the browser will invoke when a matching event occurs. 7.) element.addEventListener registers an event listener. You can also use specific GlobalEventHandlers like element.onclick, to register an event handler. 8.) The Event object provides the useful properties type, target, and currentTarget. 9.) Keyboard events have properties like key (and others) describes the keys the user pressed. Mouse events similarly provide button, clientX, and clientY. 10.) Events propagate in three phases: capturing, target, and bubbling. event.preventDefault prevents default browser behavior in response to an event. 11.) event.stopPropagation stops the current capturing or bubbling phase, which prevents the event from firing on containing or contained elements. 12.) Event delegation is a technique used to handle events triggered by multiple elements using a single event handler.
JS230 Quiz 1: Starting from the document.body node of the following HTML, if we were to use the walk function from this assignment how many times will the walk function be called? <!doctype html> <html> <head> <title>Newsletter Signup</title> </head> <body> <!-- A short comment --> <h1>Newsletter Signup</h1> <p class="intro"> To receive our weekly emails, enter your email address below. <a id="simple" href="info.html">Get more info</a> </p> <div class="form"> <form> <label> Enter your email: <input name="email" placeholder="[email protected]" /> </label> <p class="controls"> <button id="cancelButton">Cancel</button> <button type="submit" id="submitButton">Subscribe</button> </p> </form> </div> </body> </html>
33 times. You can use the following code to compute the answer:
Preventing Propagation and Default Behaviors: Stopping Propagation
A method on the event object that can affect its behavior as it moves through the capturing and bubbling phases. event.stopPropagation stops the event object from continuing its path along the capturing and bubbling phases.
Traversing Nodes in the DOM: Parent and Child Node Properties.
All DOM nodes that represent elements have both parent and child nodes. Thus, they have both sets of the above properties. Whether a node has a non-null value for a given property, though, depends on the DOM that contains the node. For example, the last child of a node has a null value for nextSibling; all other child nodes have non-null values for nextSibling.
JS230 Quiz 1: Which of the following does not represent a DOM node?
All are valid representations of a DOM type. Choice A represents a Comment node. Choice B represents an Element node. Choice C represents a Text node.
JS230 Quiz 1: Check all statements that describe what the DOM is.
Choice B isn't correct because the HTML you write isn't the DOM itself, but instead it is the input that a browser uses to create the DOM. In some instances, the browser, without any instruction, also modifies it. For example, even if you don't include a head element, a corresponding DOM head node will be present when the browser creates the DOM. Choice A isn't correct for the same reason as Choice B. When you view the source, you can see the HTML as it was written and used as the input to create the DOM.
Determining the Type of a Node: How do you actually determine the node type from code in a program?
If you're writing a program, you should probably use the instanceof function or tagName property. With element nodes, tagName returns the same value as nodeName. instanceof checks whether an object has a type that matches or inherits from a named type. The downside here is that you have to test against a particular Element type. If all you need to know, though, is whether a node is an Element, you can test it with instanceof Element: Checking an Element's type in this way is common in code that must process two or more different Element types with different actions based on the Element type. If you don't need to know the type name, you can use the tagName property to check its HTML tag name instead. (Remember that this property has an uppercase value.) > p.tagName; = "P"
What does the capturing and bubbling mechanism imply in regards to events?
Implies that events do not start and end on the target element or the element that an event was triggered on. Let's take the case of scenario 2 where we were able to interact with the child elements even though an event listener was only attached to their parent. We could interact with the child elements because when we clicked on a child element, the click event bubbled up — from the target — and passed the parent object which had a listener for it. Taking the case of scenario 3, the mechanism of capturing and bubbling also explains why there are two alert boxes when we click on the div#elem4 element only once; the event that was triggered by clicking on the div#elem4 element starts from the window object then reaches the target/div#elem4 element — invoking/calling its event handler — and then moves back up to the window object — passing the parent div#elem1 element and firing its event handler. This also shows that the click event listeners, by default, are listening on the bubbling phase because the alert box on the div#elem1 element shows up last.
Finding DOM Nodes: Finding An Element By Id
In HTML/JavaScript applications, we often need to find an element based on its id attribute. The built-in method getElementById on document provides this behavior. This technique works well when we want to find a single element with its id, more often though, we want a list of elements that match some criteria, such as a list of all p elements or all elements that belong to the find-me HTML class. In fact, it's often easier to maintain your application if you structure the code to find all matching elements instead of just one.
JS230 Quiz 2: The following code demonstrates that code isn't always executed in sequence. Is it an example of asynchronous code? function logger(object) { // 1 console.log(object); // 4 5 6 7 } let numbers = [3, 7, 25, 39]; // 2 numbers.forEach(logger); // 3 console.log(numbers.length); // 8
It doesn't demonstrate asynchronous code. JavaScript still evaluates one line at a time until the program finishes; it doesn't stop executing until it completes. It still executes lines of code sequentially, though each line may be someplace other than the next line in the file.
What is asynchronous code?
It doesn't run continuously or even when the runtime encounters it. To illustrate how asynchronous code works, we need a way to make our code wait and run later. setTimeout is a function that takes two arguments: a callback function and a time to wait specified in milliseconds (1/1000th of a second). It sets a timer that waits until the given time delay elapses, then invokes the callback function: setTimeout is not part of the JavaScript specification. Most environments (e.g., modern browsers and Node.JS) have schedulers that make it available.
When should you call preventDefault or stopPropagation in your program?
It's good practice to call preventDefault or stopPropagation as soon as possible in an event handler. Doing so emphasizes the presence of those methods to people reading the code. It also ensures that these methods run before any errors occur; not running these methods before an error occurs can lead to unexpected behavior that is hard to debug.
Finding DOM Nodes: Finding More Than One Element manually......
Suppose we need to add another paragraph to our simple HTML page above? Since we must use unique id values, we can't duplicate the id attribute. Instead, we need to choose a new id value for the new paragraph and update our JavaScript code to find and process both elements. This copy and paste approach is tedious and repetitive; we need something better. You've learned to traverse the DOM by walking the tree and by using relationship properties on each node to access its siblings, children, and parent. These techniques are cumbersome and require a lot of boilerplate, even for the simplest operations. We need a better way.
What are empty nodes in DOM diagrams?
Text nodes that contain nothing but whitespace. We show two different text node types for clarity, but, in fact, all text nodes are the same. Developers, though, sometimes make a distinction between empty nodes (spaces, tabs, newlines, etc.) and text nodes that contain content (words, numbers, symbols, etc.). Empty nodes typically arise from whitespace before and after tags in the HTML; for example, the gap between </h1> and <p> forms an empty node that contains a newline and two space characters. Developers often forget about these empty nodes since they aren't visible in the HTML, which can lead to bugs. For example, if your application expects to find an element node next to another element node, it may become confused if it finds an empty node instead. You'll learn why this is a problem later in this lesson; for now, you should know that empty nodes are not reflected visually in the web browser. Empty nodes can appear pretty much anywhere.
Traversing Elements: what is the best strategy for updating text with JavaScript?
The best strategy for updating text with JavaScript is to place the text you need to update within an element; the element type doesn't matter -- even a bare span or div element will suffice. This approach makes using textContent simpler and safer to use. Consider how you would update the time on this page: <!doctype html> <html lang="en-US"> <head> <title>My Site</title> </head> <body> <div> Welcome to the site!<br> The time is 9:15 am.<br> You are logged in as <a href="/account">Kabu</a>. </div> </body> </html> Finding the text node you must update would be tricky; replacing the time would probably require a regular expression. var div = document.querySelector('div'); var node; var newText; for (let index = 0; index < div.childNodes.length; index += 1) { node = div.childNodes[index]; if (node instanceof Text && node.nodeValue.indexOf('The time is') !== -1) { newText = node.nodeValue.replace(/\d{1,2}:\d{2} [ap]m/, '9:16 am'); node.nodeValue = newText; } }
JS230 Quiz 2: It makes code easier to maintain by reducing the number of event listeners that you need to add to a page.
The default behavior that was prevented was for the mouseover event. To prevent the default behavior of the click event, 'mouseover' should be replaced with 'click'.
Traversing Nodes in the DOM: The downside to the initial walk function and the Solution!
The downside to this implementation is that walk both walks the tree and does something with each node, which makes it hard to reuse the node-walking functionality without duplicating code. A better solution separates walk into two functions: one walks the tree (we'll continue to call it walk) and another does something with a node. We'll pass the second functions to walk as an argument: This separation of processing converts walk from a single-purpose function into a general-purpose, higher-level function we can use in any application. It's analogous to Array.prototype.forEach and other Array methods we've seen, but we use it with DOM nodes, not Arrays.
Finding DOM Nodes: Using CSS Selectors
The last problem was starting to get messy due to the nested structure of the element in the DOM. As the DOM becomes larger and more complex, finding a given subset of element also grows more complicated. The proliferation of JavaScript libraries and frameworks have popularized an alternate way to find elements. Instead of searching for a tag name, class name, or relationship, these tools use CSS selectors to find elements with minimal effort. Selector searches have become so common that web browsers now provide built-in support for selector searches with these two methods. Note that both take multiple css selectors as an argument. The argument is a string of one or more comma-separated css selectors. To better visualize this, let us use both in an example using the following markup. They differ chiefly in that the former returns the first matching element while the latter returns all matching elements. Note that both these methods are available on all elements, not just document. As with getElementsByClassName and getElementsByTagName, querySelectorAll returns array-like objects, so you'll need to keep that in mind. Don't use forEach on these objects if you care about browser compatibility.
All DOM Nodes have certain properties in common: nodeName
This property contains a String that represents the node type. For Elements (anything that represents an HTML tag), this is the name of the corresponding tag in uppercase. The use of uppercase is a historical throwback to a time when standard practice was to write uppercase HTML tags; contemporary HTML uses lowercase tags, but this method still returns uppercase names.
All DOM Nodes have certain properties in common: nodeValue
This property references the value of a node. Element nodes don't have values. Text nodes do, though. For a text node, the nodeValue is the textual content of the node. Let's look at our paragraph. To start, first extract the first text node from the DOM. The local variable, t, now references the first child within the paragraph. By checking nodeName and the return value of toString, we learn that t is a text node, that its nodeName is "#text", and that its type is Text. Since the p node represents the <p> tag, its child nodes represent its contents; here, we have some text and a link. The first child node of p (t) has a nodeValue property that contains the first sentence of text from the paragraph:
Although it's common to call the moment when the DOM is ready for interaction the DOM Ready Event but......
This term is imprecise; it isn't clear what it refers to beyond the concept that the DOM is ready for use. The name became commonplace when jQuery introduced the $.ready method; it provides a DOMContentLoaded event-like functionality in older browsers that don't support that event natively or reliably.
Creating and Moving DOM Nodes: Node Creation Example
Thus far, we've modified existing nodes in the DOM. It's time to learn how to create, add, and remove nodes. We'll use the following HTML: <!doctype html> <html lang="en-US"> <head> <title>Empty Page</title> </head> <body> </body> </html>
Page Lifecycle Events
We learned how to use an event listener to run JavaScript code when the DOMContentLoaded event on document fires: document.addEventListener('DOMContentLoaded', event => { // Do something with the DOM }); Unless you understand how a web browser renders a page, the purpose of this code is unclear. Identifying when the page finishes loading isn't easy; web pages are intricate, and the precise moment that a page load completes depends on how you define "complete" and "page." We typically use the DOMContentLoaded event when we have JavaScript code that must access the DOM. The load event fires much later, after everything on the page loads, including images, videos, etc. This load event is not useful in most cases because it may not occur for a long time after the page first appears.
Repeating Execution with setInterval
We've seen how setTimeout lets us register code that runs later: setTimeout(() => { // Do something after 300 milliseconds }, 300); Another Function, setInterval, does something similar. Instead of invoking the callback once, though, it invokes it again and again at intervals until told to stop. Like setTimeout, setInterval is also not part of the JavaScript specification and most environments also make it available. setInterval returns an identifier that we can later pass to clearInterval to cancel the timer and stop the repeated execution of the callback. setInterval is useful when you must run some code at regular intervals. For instance, perhaps you need to auto-save a user's work in a large web form:
JS230 Quiz 1: Given the following HTML: <div> Hello, world! </div> Will the following code log true? Why or why not? let text1 = document.querySelector('div').firstChild.nodeValue; let text2 = document.querySelector('div').textContent; console.log(text1 == text2);
Yes. The string values returned by the two methods are the same. In this case, it just so happens the firstChild of the div element is the only child node and as such the value becomes equivalent to the textContent.
Creating and Moving DOM Nodes: Adding Nodes to the DOM: Parent Node Methods
You can append, insert, and replace nodes with methods on the node's parent. No Node may appear twice in the DOM. If you try to add a node that is already in the DOM, it gets removed from the original location. Thus, you can move an existing node by inserting it where you want it.
Creating and Moving DOM Nodes: Creating New Nodes
You can create nodes in two ways: you can create new empty nodes with the document.create* methods, or you can clone an existing node hierarchy. If deepClone is true, cloneNode makes copies of node and all its children; otherwise, cloneNode merely copies node. Don't rely on a specific default value for deepClone; it has changed over time, so always specify true or false to get what you want. In most cases, you'll use true to get a copy of the node and its children.
Determining the Type of a Node: Inheritance in the DOM, How do all these different types relate?
You can think of them as a hierarchy where types on the right inherit properties and methods from types on the left. Here is what you need to remember about the different types: - EventTarget provides the event-handling behavior that supports interactive web applications. - Node provides common behavior to all nodes. - Text and Element are the chief subtypes of Node. Text nodes hold text and Element nodes represent HTML tags. - Most HTML tags map to specific element subtypes that inherit from HTMLElement. - Other element types exist, such as SVGElement and its subtypes.
How can you tell if code is asynchronous or not?
You can't determine whether code is asynchronous solely by looking at it. If it calls any functions, then you must be familiar with the behavior of each of those functions to determine whether any are asynchronous. You must also know whether the code you're looking at was invoked asynchronously. Ultimately, working with asynchronous code means you must reason about both what the code does and when it does it. In this lesson, we'll look more deeply at why and when you must write asynchronous code yourself, and also which DOM APIs are asynchronous.
Finding DOM Nodes: getElementsByTagName and getElementsByClassName
getElementsByTagName is so useful that the DOM provides a similar method for all elements, and another method that does the same thing for class names. One key way in which these methods differ from the one we wrote above is that they return array-like objects, not actual arrays.
Starting with the document node, use the lastChild and childNodes properties to change the text color to red on the On the River heading and set its font size 48 pixels. <!doctype html> <html lang="en-US"> <head> <title>On the River</title> </head> <body> <h1>On the River</h1> <p>A poem by Paul Laurence Dunbar</p> <p> The sun is low,<br> The waters flow,<br> My boat is dancing to and fro.<br> The eve is still,<br> Yet from the hill<br> The killdeer echoes loud and shrill. </p> <p> The paddles plash,<br> The wavelets dash,<br> We see the summer lightning flash;<br> While now and then,<br> In marsh and fen<br> Too muddy for the feet of men, </p> <p> Where neither bird<br> Nor beast has stirred,<br> The spotted bullfrog's croak is heard.<br> The wind is high,<br> The grasses sigh,<br> The sluggish stream goes sobbing by. </p> <p> And far away<br> The dying day<br> Has cast its last effulgent ray;<br> While on the land<br> The shadows stand<br> Proclaiming that the eve's at hand. </p> </body> </html>
let html = document.childNodes[1]; // skip doctype let body = html.lastChild; // skip head and text nodes let heading = body.childNodes[1]; // skip text node heading.style.color = 'red'; heading.style.fontSize = '48px';