What is the DOM

DOM connects a page to a script or programming language (usually JavaScript). DOM model uses a logical tree to represent a document. Each branch of the tree ends in a node, and each node contains objects. The DOM’s methods allow you to manipulate the tree in specific ways that can change the structure, style, or content of the document. Nodes can be associated with event handlers that will be executed once an event is fired.

Node (the node)

  1. Element nodes, such as ,

    ,

      , etc. < HTML > is the root element, the name of the tag is the name of the element, and the element can contain other elements.
  2. Text nodes, such as

    elements containing the text “What is text node”, are always contained within the element node.

  3. Attribute node. For example, the

    element has the attribute title = ‘I am Attribute node’. The attribute node is always contained in the element node.

Summary of common API – add, delete, change and check

increase

  1. document.createElement(label)Create an element node
  2. document.createTextNode(text)Create a text node
  3. node.cloneNode(deep: boolean)— Clone a node. If the parameter is ‘deep’, clone the node deeply. Otherwise, clone only one layer

delete

  1. parent.removeChild(childNode)Delete a child node. The child node is removed from the DOM tree but still exists in memory

change

  1. parent.appendChild(childNode)Add a child node to the parent node, or add the end if there are more than one child node
  2. parent.insertBefore(newNode, refNode)— add the newNode (newNode) before the specified node (refNode)
  3. parent.replaceChild(newNode, oldNode)— replace oldNode with newNode (oldNode)
  4. node.setAttribute(attribute, value)— Sets the properties of the node

check

  1. doucument.getElementById(id)Returns an object by id
  2. document.getElementsByTagName(label)Returns an array of objects by label name
  3. document.getElementsByClassName(class)Returns an array of objects by class name
  4. document.querySelector(.css)The CSS selector returns the first element that meets the condition
  5. document.querySelectorAll(.css)Search through the CSS selector and return all elements that meet the criteria
  6. node.getAttribute(attribute)— Find attributes on the node

The biggest appeal of DOM

Refreshing the page content without refreshing the page in the browser.

Practice is the mother of wisdom

Marvel Photo Gallery

<! DOCTYPEhtml>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="Width = device - width, initial - scale = 1.0" />
    <title>Photo gallery - DOM</title>
  </head>
  <body>
    <h1>Marvel Heroes pool</h1>
    <ul>
      <li>
        <a
          href="img/gangtie.jpg"
          title="Sacrifice your life for mine."
          onclick="showPic(this); return false"
          >Iron Man </a ></li>
      <li>
        <a
          href="img/leishen.jpg"
          title="The God of Thunder."
          onclick="showPic(this); return false"
          >The thor < / a ></li>
      <li>
        <a
          href="img/heibao.jpg"
          title="Wakanda Forever."
          onclick="showPic(this); return false"
          >Panther < / a ></li>
      <li>
        <a
          href="img/meidui.jpg"
          title="Captain America wields thor's hammer."
          onclick="showPic(this); return false"
          >Captain America </a ></li>
    </ul>
    <img id="placeholder" src="img/manwei.jpg" alt="Diffuse wei" />
    <p id="description">Choose an image</p>
  </body>

  <script>
    function showPic(whichPic) {
      const src = whichPic.getAttribute("href");
      const placeholder = document.getElementById("placeholder");
      placeholder.setAttribute("src", src);
      const text = whichPic.getAttribute("title");
      const description = document.getElementById("description");
      description.firstChild.nodeValue = text;
    }
  </script>
</html>
Copy the code

Graceful degradation

Jeremy Keith defines it this way in his DOM Scripting — if JavaScript is used correctly, it will allow visitors to navigate your site even if their browser does not support JavaScript. In layman’s terms, even if some functionality is not available, the most basic operations can still be done.

Why do we need smooth degradation

  1. Imagine someone browsing the Web with both images and JavaScript disabled. You’d think that person would be rare these days, and it is, but this visitor is very important.
  2. If that user is a search bot. Search robots are automated programs that browse the Web in order to add Web pages to a search engine’s database. All the major search engines have similar programs, and very few search bots currently understand JavaScript code. So, if your JavaScript web pages don’t degrade smoothly, their search engine rankings may suffer.

Does Marvel Photo Gallery support smooth degradation?

First question: What happens if you disable JavaScript functionality?

Conclusion: The script has a backstop for this, even if JavaScript is disabled, the user can still view all images in the gallery, which means basic functionality is not affected. It would be useless to write it as:

<a
  href="#"
  title="Wakanda Forever."
  onclick="showPic('img/heibao.jpg'); return false"
  >Panther < / a >Copy the code

Second question: Are the behavioral and structural layers of a web page separated? In layman’s terms: Are its JavaScript and HTML tags separate?

Verdict: Mixed, of course

Ideally, adding the onclick event handler should be done in an external file so that the tag document is free of “impurities.”

Improvements: Write a short function that associates the action to the onclick event. I’ll call it prepare. Here’s what it will do:

  1. Check whether the current browser understandsgetElementsByTagName
  2. Check whether the current browser understandsgetElementById
  3. Check whether the current web page has an IDimagesThe elements of the
  4. traverseimagesAll links in the element
  5. Set up theonclickEvent that causes it to pass the related link when it is clickedshowPicFunction and cancels the default behavior.
function prepare() {
  if (!document.getElementsByTagName) return false;
  if (!document.getElementById) return false;
  if (!document.getElementById("images")) return false;
  const images = document.getElementById("images");
  const links = images.getElementsByTagName("a");
  for (let i = 0; i < links.length; i++) {
    links[i].onclick = function() {
      showPic(this);
      return false; }; }}Copy the code

One thing missing is when to execute this function: I choose to execute it immediately after the page loads. When the page is loaded, an onload event is triggered, which is associated with the window object, so:

window.onload = prepare;
Copy the code

But that’s far from enough. What if I have two functions that NEED to be executed:

window.onload = firstFunc;
window.onload = secondFunc;
Copy the code

Obviously, firstFunc will be overwritten by secondFunc, so I thought of an alternative: I could create an anonymous function to hold both functions, and then bind this anonymous function to the onLoad event

window.onload = () = > {
  firstFunc();
  secondFunc();
}
Copy the code

This is really a solution, if you don’t have a lot of functions.

Here’s another best solution for elasticity, addLoadEvent by Simon Willison. It takes only one argument: the name of the function you intend to execute when the page loads. There are three steps

  1. The existingwindow.onloadEvent handlers are stored in variablesmyOnloadIn the
  2. If there are no functions bound to the handler, add the new function directly to it
  3. If some functions are already bound, the new function is added to the end of the instruction

Here is the code listing for addLoadEvent

function addLoadEvent(func) {
  let myOnload = window.onload;
  if (typeof window.onload ! = ="function") {
    window.onload = func;
  } else {
    window.onload = () = >{ myOnload(); func(); }; }}Copy the code

This is actually using the queue idea. If you want to add the previous two functions, you just need to:

addLoadEvent(firstFunc);
addLoadEvent(secondFunc);
Copy the code

So to make my prepare function run smoothly, I added the following code

addLoadEvent(prepare)
Copy the code

Don’t assume too much

The prepare function I wrote calls showPic.

The first problem I found with the showPic function was that it wasn’t tested or checked at all. The getElementById and getElementsByTagName DOM methods were checked in the prepare function, but showPic didn’t.

The showPic code listing after adding the check is as follows:

function showPic(whichPic) {
  if (!document.getElementById("placeholder")) return false;
  if (!document.getElementById("description")) return false;
  const src = whichPic.getAttribute("href");
  const placeholder = document.getElementById("placeholder");
  placeholder.setAttribute("src", src);
  const text = whichPic.getAttribute("title");
  const description = document.getElementById("description");
  description.firstChild.nodeValue = text;
  return true
}
Copy the code

There are now placeholder and description elements in the document without any JavaScript errors

But there’s one more question, what happens if I delete the ID =”placeholder” and refresh the page?

The conclusion is that no matter which link is clicked, nothing happens.

Because I assumed showPic must return true in Prepare, I permanently disallowed the default behavior of the tag, so I made the following change:

links[i].onclick = function () {
  // The default behavior is disallowed if true, and not if false
  return! showPic(this);
};
Copy the code

The showPic function still has some errors to handle, such as assuming that every link has a title attribute, which is better written as follows

const text = whichPic.getAttribute("title")? whichPic.getAttribute("title") : "";
Copy the code

This way, even if my tag doesn’t have a title attribute, it becomes an empty string.

conclusion

If you want to be perfect, you can check in either case, but with more code, you have to decide if you really need these checks in practice.

This article is a summary of the art of JavaScript DOM Programming (version 2) for those interested. Please contact me if there is any infringement.