Skip to content

Latest commit

 

History

History

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 
 
 
 
 
 
 
 
 
 
 

README.md

📚 Browser API

  It is a set of interfaces and methods that allow developers to interact with web browsers. The Browser API is what makes it possible for developers to create dynamic and interactive web applications.

📖 DOM-BOM

Document Object Model

DOM is interface that allows JS to access and manipulate structure and content of HTML or XML document. DOM is hierarchical tree-like structure that represents web page, with each element representing different part of page, such as headings, paragraphs, images, and links. Developers use DOM to access and modify properties and attributes of these elements, such as their text content, styles, and event handlers.

  • Fetching
    • index.html
  • Parsing
    • Render Tree (WebKit)
    • Frame Tree (Gecko)
    • CSSOM (CSS Object Model)
  • Layout
  • Paint
    • background-color; >> background-image; >> border; >> children; >> outline;
  • Compositing

Browser Object Model

BOM, on the other hand, provides JS with access to browser window and its components, such as location bar, history, and navigation buttons. BOM also provides interfaces for working with cookies, timers, and browser's user interface.

  • navigator
    • User-Agent Client Hints
  • screen
  • location
  • Fetch
  • history
  • pageX/pageY
    • pageXOffset
    • pageYOffset
  • clientX/clientY
    • clientXOffset
    • clientYOffset

Basics of DOM Manipulation in Vanilla JavaScript

 There are several ways to manipulate the DOM using JavaScript.

  1. Accessing DOM elements:
    using document object and one of its methods
    getElementById(), getElementsByClassName(), getElementsByTagName(), or querySelector();
  2. Modifying element content:
    using its properties
    textContent, innerHTML, or outerHTML;
  3. Modifying element attributes:
    using its setAttribute() method;
  4. Modifying element styles:
    using its style property
  5. Creating new elements:
    using createElement() and appendChild() methods;
  6. Removing elements:
    using its remove() method;
  • NodeList
    • stores any nodes (including comments and text);
    • can be both a "live" collection (getElementsByName and childNodes) and a static one (querySelectorAll);
       let myElement = document.querySelector("#foo > div.bar"); 
       //If there are no required elements, null will be returned.
       const myChildElement = myElement.querySelector('input[type="submit"]');
    • method .querySelectorAll() returns an array-like static NodeList collection of found elements;
       let myElements = document.querySelectorAll("div>p");

      to search for all elements in general, you need to pass string '*', which is called a wildcard, as an argument;

To work with collection of elements, we must convert list to array or "borrow" array methods from Array prototype.

 Array.from(myElements).forEach(doSomethingWithEachElement);
   Array.from(myElements).forEach( (item) => {  item.classList.add('foo'); } );
 Array.prototype.forEach.call(myElements, doSomethingWithEachElement); 
  • HTMLCollection
    • save only HTML element nodes;
    • always remains relevant — JS will update it when new element appears;
    • method .getElementById('idName') is only in document object (good for unique elements: title, form);
       let divAll = document.getElementsByTagName("div");
       const newElement = document.createElement('div'); //creates new element with given tag
         document.body.appendChild(newElement);
       let myElement = document.querySelector("div");    
       const myNewTextNode = document.createTextNode('some text'); // creates new text node with given text
         myElement.appendChild(myNewTextNode);
    • method .getElementsByClassName('class1 class2') defined for any HTML-Element of page;

Take your time writing loops over HTMLCollection. Because cycle can become infinite in those cases when searchable elements are added and removed from page.


HTML attribute values can be read and written using element properties.

  • to set class:
    • element.className = "hacked";
      • element.className.add('hello');
      • element.className.remove('bye');
  • add or remove multiple classes:
    • button.classList.add('active', 'paralel');
    • button.classList.remove('active');
  • to set styles:
    • element.style.marginTop = "20px";
    • element.style.color = "gray";
    • element.style.backgroundColor = "beige";
    • elem.style.cssText = "color: blue; border: 1px solid black";
  • get a child or parent element:
    • myElement. children
    • myElement.firstChild or myElement.lastChild
    • myElement.parentElement
  • get the next/previous neighbor node:
    • myElement.nextElementSibling or myElement.previousElementSibling
  • internal content of elements:
    • El.innerHTML returns the HTML code of everything in the current element (the easiest way to see the HTML content of an element)
    • El.innerText for working with text
    • El.textContent returns the contents of hidden nested children as well (use to add text)
    • outerHTML returns the HTML code of both this element and everything in it
  • attribute management:
    • element.setAttribute("style", "color: red; border: 1px solid blue;");
    • someElement.getAttribute('id' || 'class' || 'type');

Date attributes are used to store values on HTML elements. When the server compiles the starting HTML, it can put values in data attributes. The frontend can then use them instead of sending the request to the server.

  • elem.dataset.columns - the value of the data-columns attribute;

To delete a node: element.remove();


insertAdjacentHTML/Text/Element


Web Storage

  • Local Storage (for long-term data storage) >>>
    • we specify name of field in which data (up to 5MB) should be saved (values in form of strings), and then use this name to retrieve it;
    • this object is one for all tabs and windows within the source (same domain/protocol/port);
    • if we set data in one window, changes become visible in another;
      • write: window.localStorage.setItem("name", "Doka SKj");
      • read: const name = window.localStorage.getItem("name");
      • remove: window.localStorage.removeItem("user");
      • clear: window.localStorage.clear();
  • Session Storage (data is stored only during the lifetime of the current session) >>>
    • is created when a new browser tab is opened. The amount of data is limited to 5MB;
    • page session remains active as long as the browser window is open and persists between page reloads;
    • values are stored in order they are added, so first one added will be stored in position .key(0) and so on.

Use wrapper functions to prevent errors related to failed write attempts, missing localStorage in the browser, and code duplication.

 function setItem(key, value) {
   try { return window.localStorage.setItem(key, value) 
   } catch (e) { console.log(e) }
 } 
 function getItem(key) {
   try { return window.localStorage.getItem(key)
   } catch (e) { console.log(e) }
 }
 function setJSON(key, value) { 
   try {
     const json = JSON.stringify(value) 
     setItem(key, json)
   } catch (e) { console.error(e) }
 }
 function getJSON(key) {
   try {
     const json = getItem(key)
     return JSON.parse(json)
   } catch (e) { console.error(e) }
 }

A global storage event is fired, which can be used to track changes in storage. This event occurs only on other open pages of the current site. The event contains properties: key - the key that was changed; oldValue - the old value recorded in the field; newValue - new value; url - the address of the page where the change was triggered.

 window.sessionStorage.setItem("name", "Doka SKj")
   function readUser() { const userJSON == sessionStorage.getItem("user")
     if (userJSON === null) { return undefined } 
       try { return JSON.parse(userJSON)
       } catch (e) {sessionStorage.removeItem("user"); 
           return undefined }
   }

📖 Web API

 Global Window object is an object that provides access to the browser's Web API.

 In fact, if the programs are written in different languages, it can be difficult to make them friends and make them communicate with each other. That's why APIs (Application Programming Interface) exist.
 JavaScript objects are very useful for transferring data from one site to another, especially when using APIs.

API - structured form of communication between different applications.
REST (Representational State Transfer) - component communication style in which all required data is specified in request parameters.
  The interaction between the client and the server is reduced to 4 operations

C R U D
create read update delete
POST GET PUT, PATCH DELETE

RPC (Remote Procedure Call) - is a style in which request message stores action to be performed and data required for that action.
JSON-RPC must have the following fields:

method params id
"name of method" [array of data] establish compliance

XMLHttpRequest is a built-in browser object that allows you to make HTTP requests to the server without reloading the page. XMLHttpRequest has two modes of operation: synchronous and asynchronous.

To make a request, we need to complete three steps:

  1. Create an XMLHttpRequest.
    • let xhr = new XMLHttpRequest();
  2. Initialize it.
    • xhr.open(method, URL, async = true, user, password);
      • HTTP method(usually "GET" or "POST");
      • URL where the request is sent;
  3. Send a request.
    • xhr.send([body]);

Next, we listen to events on xhr to get the answer:

  • load – occurs when any response is received, including HTTP error responses such as 404.
  • error – when the request cannot be fulfilled, for example, there is no connection or URL.
  • progress - occurs periodically while loading a response, reports progress.

Here is a complete example.

let xhr = new XMLHttpRequest();
xhr.open('GET', '/article/example/load');
xhr.send();
	xhr.onload = function() {
		if (xhr.status != 200) {  // analyze HTTP status of response
			alert(`Error ${xhr.status}: ${xhr.statusText}`);    // 404: Not Found
		} else { alert(`Done, received ${xhr.response.length} byte`);  // this is server response
  } };
  xhr.onprogress = function(event) { 
    if (event.lengthComputable) { alert(`Received ${event.loaded} of ${event.total} byte`);
	  } else { alert(`Received ${event.loaded} byte`); 
  } };
  xhr.onerror = function() { alert("The request failed"); };

AJAX (Asynchronous JavaScript and XML) allows us to access information from external pages even after our page has loaded.
fetch function allows us to send HTTP requests to the server. With its help, you can both receive and send data.
Result of the fetch call will be a Promise (a wrapper object for asynchronous code) - this is something that will happen between now and the final moment in time (something that will happen in the future, but probably not immediately).

If you are working with JSON API, you will need to check status and parse JSON for each response. You can simplify your code by defining status parsing and JSON parsing as separate functions that return Promises.
You will only have to think about handling the data itself and, of course, exceptions.

function status(response) {  
  if (response.status >= 200 && response.status < 300) {  
    return Promise.resolve(response)  
  } else { return Promise.reject(new Error(response.statusText)) }  
};
function json(response) { return response.json() }

fetch('users.json')  
  .then(status)  
  .then(json)  
  .then(function(data) { console.log('Request succeeded with JSON response', data); })
  .catch(function(error) { console.log('Request failed', error); });

fetch() method can take a second parameter, the init object, which allows you to control various settings:

An example of sending a POST request:

async function postData(url = '', data = {}) {
  // Default options are marked with *
  const response = await fetch(url, {
    method: 'POST', // *GET, POST, PUT, DELETE, etc.
    mode: 'cors', // no-cors, *cors, same-origin
    cache: 'no-cache', // *default, no-cache, reload, force-cache, only-if-cached
    credentials: 'same-origin', // include, *same-origin, omit
    headers: {
      'Content-Type': 'application/json'
      // 'Content-Type': 'application/x-www-form-urlencoded',
    },
    redirect: 'follow', // manual, *follow, error
    referrerPolicy: 'no-referrer', // no-referrer, *client
    body: JSON.stringify(data) // body data type must match "Content-Type" header
  });
  return await response.json(); // parses JSON response into native JavaScript objects
}

postData('https://example.com/answer', { answer: 42 })
  .then((data) => {
    console.log(data); // JSON data parsed by `response.json()` call
  });

📖 Web Workers

 Web Workers are a type of browser API that allow web applications to run scripts in the background on a separate thread, independent of the main execution thread. This can be useful for tasks that are CPU-intensive or time-consuming, such as large computations or complex data processing.
 Web Workers operate in a separate context from the main execution thread, and communicate with the main thread via a messaging system. This messaging system allows the main thread to pass data to the worker thread, and vice versa.
 Web Workers are instantiated using the Worker constructor, and are terminated using the terminate() method. When a worker is terminated, all its resources are released and its memory is freed.
 One important thing to note about Web Workers is that they have limited access to the browser's APIs. For example, a worker cannot directly access the DOM or make network requests. However, a worker can communicate with the main thread to request this information.

Web Workers can be used for a variety of tasks, such as:

  • Processing large datasets or performing complex calculations without blocking the main thread
  • Parsing and validating large amounts of data
  • Running tasks in the background while the user interacts with the application
  • Creating multiplayer games or real-time applications that require synchronization between multiple clients