<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/"
    xmlns:atom="http://www.w3.org/2005/Atom" xmlns:media="http://search.yahoo.com/mrss/" version="2.0">
    <channel>
        
        <title>
            <![CDATA[ DOM - freeCodeCamp.org ]]>
        </title>
        <description>
            <![CDATA[ Browse thousands of programming tutorials written by experts. Learn Web Development, Data Science, DevOps, Security, and get developer career advice. ]]>
        </description>
        <link>https://www.freecodecamp.org/news/</link>
        <image>
            <url>https://cdn.freecodecamp.org/universal/favicons/favicon.png</url>
            <title>
                <![CDATA[ DOM - freeCodeCamp.org ]]>
            </title>
            <link>https://www.freecodecamp.org/news/</link>
        </image>
        <generator>Eleventy</generator>
        <lastBuildDate>Tue, 02 Jun 2026 17:11:32 +0000</lastBuildDate>
        <atom:link href="https://www.freecodecamp.org/news/tag/dom/rss.xml" rel="self" type="application/rss+xml" />
        <ttl>60</ttl>
        
            <item>
                <title>
                    <![CDATA[ What is the Virtual DOM in React? ]]>
                </title>
                <description>
                    <![CDATA[ As web applications become more complex, managing updates to the user interface becomes a challenging task. This is where the Virtual DOM (Document Object Model) comes into play – particularly in React, the leading JavaScript library for building use... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/what-is-the-virtual-dom-in-react/</link>
                <guid isPermaLink="false">66bc4d2973c9920bb20c0e0c</guid>
                
                    <category>
                        <![CDATA[ DOM ]]>
                    </category>
                
                    <category>
                        <![CDATA[ React ]]>
                    </category>
                
                    <category>
                        <![CDATA[ virtual dom ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Matéu.sh ]]>
                </dc:creator>
                <pubDate>Wed, 05 Jun 2024 14:51:11 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2024/06/Virtual-DOM.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>As web applications become more complex, managing updates to the user interface becomes a challenging task. This is where the Virtual DOM (Document Object Model) comes into play – particularly in React, the leading JavaScript library for building user interfaces.</p>
<p>The virtual DOM is a lightweight copy of the real DOM that allows React to manage changes more efficiently by minimizing the direct manipulation required on the real DOM. This process significantly enhances the performance of web apps.</p>
<p>Understanding the virtual DOM is essential for developers who want to get the best out of React. It plays a key role in how React updates the UI, ensuring that changes are applied quickly without unnecessary re-renders.  </p>
<p>In this article, you'll learn:</p>
<ul>
<li>What the virtual DOM is and how it works</li>
<li>How the virtual DOM compares to the real DOM</li>
<li>Benefits of using the virtual DOM</li>
<li>How React uses the virtual DOM</li>
<li>How the virtual DOM compares to the shadow DOM</li>
<li>Common misconceptions about the virtual DOM</li>
</ul>
<h2 id="heading-what-is-the-virtual-dom-and-how-does-it-work">What Is the Virtual DOM and How Does It Work?</h2>
<p>The virtual DOM is an in-memory representation of the real DOM elements. Instead of interacting directly with the real DOM, which can be slow and costly in terms of performance, React creates a virtual representation of the UI components. This virtual representation is a lightweight JavaScript object that mirrors the structure of the real DOM.</p>
<p>Here's a step-by-step process of how the virtual DOM works:</p>
<ol>
<li><strong>Step 1 – Initial Rendering</strong>: when the app starts, the entire UI is represented as a Virtual DOM. React elements are created and rendered into the virtual structure.</li>
<li><strong>Step 2 – State and Props Changes</strong>: as the states and props change in the app, React re-renders the affected components in the virtual DOM. These changes do not immediately impact the real DOM.</li>
<li><strong>Step 3 – Comparison Using Diff Algorithm</strong>: React then uses a <strong>diffing algorithm</strong> to compare the current version of the Virtual DOM with the previous version. This process identifies the differences (or "diffs") between the two versions.</li>
<li><strong>Step 4 – Reconciliation Process</strong>: based on the differences identified, React determines the most efficient way to update the real DOM. Only the parts of the real DOM that need to be updated are changed, rather than re-rendering the entire UI. This selective updating is quick and performant.</li>
<li><strong>Step 5 – Update to the Real DOM</strong>: finally, React applies the necessary changes to the real DOM. This might involve adding, removing, or updating elements based on the differences detected in step 3.</li>
</ol>
<p>For example, let's say we have the following counter functionality in the <code>App</code> component:</p>
<pre><code class="lang-jsx"><span class="hljs-keyword">import</span> React, { useState } <span class="hljs-keyword">from</span> <span class="hljs-string">'react'</span>;

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">App</span>(<span class="hljs-params"></span>) </span>{
 <span class="hljs-keyword">const</span> [count, setCount] = useState(<span class="hljs-number">0</span>);

 <span class="hljs-keyword">return</span> (
   <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>
     <span class="hljs-tag">&lt;<span class="hljs-name">h1</span>&gt;</span>Counter: {count}<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span>
     <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">onClick</span>=<span class="hljs-string">{()</span> =&gt;</span> setCount(count + 1)}&gt;Increment<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
   <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
 );
}

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> App;
</code></pre>
<p>The virtual DOM representation will look like this:</p>
<pre><code class="lang-json">{
 <span class="hljs-attr">"type"</span>: <span class="hljs-string">"div"</span>,
 <span class="hljs-attr">"props"</span>: {},
 <span class="hljs-attr">"children"</span>: [
   {
     <span class="hljs-attr">"type"</span>: <span class="hljs-string">"h1"</span>,
     <span class="hljs-attr">"props"</span>: {},
     <span class="hljs-attr">"children"</span>: [
       {
         <span class="hljs-attr">"type"</span>: <span class="hljs-string">"TEXT_ELEMENT"</span>,
         <span class="hljs-attr">"props"</span>: {
           <span class="hljs-attr">"nodeValue"</span>: <span class="hljs-string">"Counter: 0"</span>
         }
       }
     ]
   },
   {
     <span class="hljs-attr">"type"</span>: <span class="hljs-string">"button"</span>,
     <span class="hljs-attr">"props"</span>: {
       <span class="hljs-attr">"onClick"</span>: <span class="hljs-string">"setCount(count + 1)"</span>
     },
     <span class="hljs-attr">"children"</span>: [
       {
         <span class="hljs-attr">"type"</span>: <span class="hljs-string">"TEXT_ELEMENT"</span>,
         <span class="hljs-attr">"props"</span>: {
           <span class="hljs-attr">"nodeValue"</span>: <span class="hljs-string">"Increment"</span>
         }
       }
     ]
   }
 ]
}
</code></pre>
<p>When the <code>Increase</code> button is clicked once, only the <code>h1</code> element is changed:</p>
<pre><code class="lang-json">{
 <span class="hljs-attr">"type"</span>: <span class="hljs-string">"h1"</span>,
 <span class="hljs-attr">"props"</span>: {},
 <span class="hljs-attr">"children"</span>: [
   {
     <span class="hljs-attr">"type"</span>: <span class="hljs-string">"TEXT_ELEMENT"</span>,
     <span class="hljs-attr">"props"</span>: {
       <span class="hljs-attr">"nodeValue"</span>: <span class="hljs-string">"Counter: 1"</span>
     }
   }
 ]
}
</code></pre>
<h2 id="heading-comparing-the-virtual-dom-to-the-real-dom">Comparing the Virtual DOM to the Real DOM</h2>
<p>To see the advantages of the virtual DOM, it's important to understand how it differs from the real DOM. The real DOM and the virtual DOM serve similar purposes but operate in distinct ways with significant implications for performance and efficiency.</p>
<p>The real DOM is a built-in standard interface in browsers that represents and interacts with HTML elements, from <code>Doctype</code> declaration and the root <code>html</code> element to every other element in it.</p>
<p>This real DOM represents the whole HTML document as a tree structure and allows JavaScript to manipulate and change HTML documents. Sometimes when those changes occur, the whole document might re-render.</p>
<p>This is in contrast to the virtual DOM, which uses a <strong>diff algorithm</strong> to compare the current and previous versions of updates to the DOM. It only re-renders the parts of the UI that have changed, instead of the whole thing.</p>
<h2 id="heading-benefits-of-using-the-virtual-dom-in-web-development">Benefits of Using the Virtual DOM in Web Development</h2>
<h3 id="heading-simplified-development">Simplified Development</h3>
<p>The Virtual DOM lets you write code in a more declarative style. This means that instead of writing detailed instructions on how to update the UI, you can simply describe what the UI should look like, and React takes care of the rest. This is made possible by React's declarative syntax and its component-based architecture.</p>
<h3 id="heading-improved-performance">Improved Performance</h3>
<p>One of the major advantages of using the virtual DOM is the significant performance improvement it offers. Direct manipulation of the real DOM is slow and can lead to performance issues, especially in complex applications.</p>
<h3 id="heading-enhanced-user-experience">Enhanced User Experience</h3>
<p>The Virtual DOM contributes to a better UX by ensuring that UI updates are smooth, responsive, and without full-page refreshes. Users are less likely to experience lag or jank, resulting in a more seamless interaction with the app.</p>
<h3 id="heading-cross-platform-development">Cross-platform Development</h3>
<p>The principles of the Virtual DOM are not limited to web development only. React Native – a version of React for building cross-platform mobile apps – uses a similar approach. This increases productivity and reduces development time because you can reuse code across web and mobile platforms</p>
<h2 id="heading-common-misconceptions-about-the-virtual-dom">Common Misconceptions About the Virtual DOM</h2>
<p>There are a few misconceptions about the virtual DOM. Let's look at five of these misconceptions and the realities of each of them.</p>
<h3 id="heading-the-virtual-dom-is-a-browser-feature">The Virtual DOM Is a Browser Feature</h3>
<p><strong>Reality</strong>: the virtual DOM is an abstraction implemented by React, not a browser feature. Browsers have the real DOM, which is the standard way to represent and interact with HTML documents. The virtual DOM exists solely in memory within React and is used to optimize updates to the real DOM.</p>
<h3 id="heading-the-virtual-dom-replaces-the-real-dom">The Virtual DOM Replaces the Real DOM</h3>
<p><strong>Reality</strong>: The virtual DOM acts as an intermediary between React and the browser, not a replacement for the real DOM. The real DOM is still what the browser uses to render the UI, but the updates to it are managed through the Virtual DOM.</p>
<h3 id="heading-react-is-the-only-library-and-framework-that-uses-the-virtual-dom">React is the Only Library and Framework that Uses the Virtual DOM</h3>
<p><strong>Reality</strong>: React only popularized the concept of the virtual DOM, it is not the only library or framework that uses it. Other frameworks like VueJS and SolidJS also use the virtual DOM to update the UI.</p>
<h3 id="heading-the-virtual-dom-solves-all-performance-problems">The Virtual DOM Solves All Performance Problems</h3>
<p><strong>Reality</strong>: The virtual DOM can significantly improve performance, but it is not a magical solution to all problems. Poor coding practices, unnecessary renders, and large component trees can still lead to performance issues.</p>
<h3 id="heading-the-virtual-dom-and-shadow-dom-are-the-same">The Virtual DOM and Shadow DOM Are the Same</h3>
<p><strong>Reality</strong>: The virtual DOM and shadow DOM are not the same thing. The virtual DOM is a lightweight copy of the Real DOM with which React optimize UI updates. On the other hand, shadow DOM is a browser technology used to encapsulate the styles and structure of web components.</p>
<h2 id="heading-real-dom-vs-virtual-dom-vs-shadow-dom">Real DOM vs Virtual DOM vs Shadow DOM</h2>
<p>Now that we've established that the virtual DOM, shadow DOM, and real DOM are not the same, let's look at the differences between the three of them.</p>
<div class="hn-table">
<table>
<thead>
<tr>
<td><strong>Aspect</strong></td><td><strong>Real DOM</strong></td><td><strong>Virtual DOM</strong></td><td><strong>Shadow DOM</strong>  </td></tr>
</thead>
<tbody>
<tr>
<td><strong>Definition</strong></td><td>Standard browser API for representing and interacting with HTML documents</td><td>In-memory representation of the Real DOM</td><td>A browser technology that encapsulates and scopes DOM and style of web components  </td></tr>
<tr>
<td><strong>Flexibility</strong></td><td>Directly manipulated via JavaScript or DOM APIs</td><td>Abstracted and optimized by the framework</td><td>Limited to component boundaries</td></tr>
<tr>
<td><strong>Implementation</strong></td><td>Provided by the browser</td><td>Implemented by frameworks like React and Vue</td><td>Part of the Web Components standard, provided by the browser </td></tr>
<tr>
<td><strong>Performance</strong></td><td>Direct manipulation can be slow and cause performance issues</td><td>Already optimized for efficient updates</td><td>Provides encapsulation, reducing style conflicts </td></tr>
<tr>
<td><strong>Usage</strong></td><td>For rendering and interacting with web documents</td><td>For efficient UI updates by frameworks</td><td>For creating isolated, reusable web components</td></tr>
<tr>
<td><strong>Updates</strong></td><td>Immediate updates to the UI</td><td>Updates are batched and optimized</td><td>Updates are scoped to the component, not affecting the global DOM</td></tr>
<tr>
<td><strong>Repaints</strong></td><td>Frequent updates can cause costly repaints</td><td>Minimizes repaints by batching updates</td><td>Scoped to the component, reducing global repaints</td></tr>
<tr>
<td><strong>Use Cases</strong></td><td>General web development and document manipulation</td><td>Efficient UI updates in frameworks like React and Vue</td><td>Encapsulation of styles and structure in web components</td></tr>
</tbody>
</table>
</div><h2 id="heading-conclusion">Conclusion</h2>
<p>As you've read in this article, the Virtual DOM is a key React feature that enhances performance and efficient UI updates. With this, React can batch updates, minimize reflows and repaints, and apply changes efficiently. This makes UI updates fast and smooth, providing a better user experience in the process.</p>
<p>Understanding the Virtual DOM and how it works can help you build performant React applications.</p>
<h2 id="heading-learn-react-and-next-js">Learn React and Next JS</h2>
<p>Want to discover more cool React features like the virtual DOM? Enroll in my React 18 course on Udemy! I'll guide you through the React world by creating a cool 2048 game with animations from scratch.</p>
<p><a target="_blank" href="https://assets.mateu.sh/r/fcc-universal"><img src="https://assets.mateu.sh/assets/fcc-universal" alt="Next.js crash course on Udemy" width="600" height="400" loading="lazy"></a>  </p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ JavaScript in the Browser – How the Document Object Model (DOM) and Events Work ]]>
                </title>
                <description>
                    <![CDATA[ In this in-depth tutorial, you'll learn all about the Document Object Model, or DOM for short. As a web developer, understanding the DOM is fundamental for interacting with web browsers and creating dynamic web applications.  Throughout this guide, w... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/javascript-in-the-browser-dom-and-events/</link>
                <guid isPermaLink="false">66c7218887ceefbdaf9b921b</guid>
                
                    <category>
                        <![CDATA[ browser ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Document Object Model ]]>
                    </category>
                
                    <category>
                        <![CDATA[ DOM ]]>
                    </category>
                
                    <category>
                        <![CDATA[ events ]]>
                    </category>
                
                    <category>
                        <![CDATA[ handbook ]]>
                    </category>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Samyak Jain ]]>
                </dc:creator>
                <pubDate>Thu, 15 Feb 2024 20:07:14 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2024/02/JavaScript-in-the-Browser-with-Photo-Cover.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>In this in-depth tutorial, you'll learn all about the Document Object Model, or DOM for short. As a web developer, understanding the DOM is fundamental for interacting with web browsers and creating dynamic web applications. </p>
<p>Throughout this guide, we will explore the DOM's hierarchical tree structure, essential properties, and methods for accessing and modifying nodes. We'll also dive into event handling and various techniques for efficient DOM manipulation.</p>
<p>By the end of this guide, you should be able to confidently manipulate the DOM to meet the demands of your web development projects.</p>
<h3 id="heading-prerequisites">Prerequisites:</h3>
<p>While this guide is designed to be beginner-friendly and accessible to anyone, having a basic understanding of JavaScript fundamentals will greatly enhance your ability to grasp the practical concepts covered. </p>
<p>Also, familiarity with HTML and CSS is a plus and will help you comprehend and apply the material we cover. </p>
<p>If you're new to JavaScript, consider familiarizing yourself with variables, data types, functions, loops, and basic DOM manipulation techniques before diving into this tutorial. This foundational knowledge will ensure a smoother learning experience as we explore more advanced topics related to the Document Object Model (DOM).</p>
<h2 id="heading-table-of-contents">Table of Contents</h2>
<ol>
<li><a class="post-section-overview" href="#browser-object-model-bom-">What is the Browser Object Model (BOM)</a>?</li>
<li><a class="post-section-overview" href="#what-is-the-document-object-model-dom">What is the Document Object Model (DOM)?</a></li>
<li><a class="post-section-overview" href="#heading-dom-tree-structure">DOM Tree Structure</a><br>– <a class="post-section-overview" href="#heading-types-of-nodes-in-the-dom-tree">Types of Nodes in the DOM Tree</a><br>– <a class="post-section-overview" href="#heading-node-relationships">Node Relationships</a></li>
<li><a class="post-section-overview" href="#heading-how-to-work-with-dom-elements">How to Work with DOM Elements</a><br>– <a class="post-section-overview" href="#methods-for-traversing-the-dom-">Traversing the DOM</a><br>– <a class="post-section-overview" href="#heading-methods-for-querying-dom-elements">Methods for Querying DOM Elements</a><br>– <a class="post-section-overview" href="#heading-matches-closest-and-contains">Specialized Selectors (Matches, Closest, Contains)</a><br>– <a class="post-section-overview" href="#heading-how-to-inspect-dom-elements">How to Inspect DOM Elements</a><br>– <a class="post-section-overview" href="#heading-table-navigation-in-the-dom">Table Navigation in the DOM</a></li>
<li><a class="post-section-overview" href="#heading-how-to-modify-dom-elements">How to Modify DOM Elements</a><br>– <a class="post-section-overview" href="#heading-how-to-manipulate-element-content-and-visibility">How to Manipulate Element Content and Visibility</a><br>– <a class="post-section-overview" href="#heading-how-to-modify-element-attributes">How to Modify Element Attributes</a><br>– <a class="post-section-overview" href="#heading-html-insertion-methods">HTML Insertion Methods</a><br>– <a class="post-section-overview" href="#heading-how-to-manipulate-classes-with-javascript">How to Manipulate Classes with JavaScript</a></li>
<li><a class="post-section-overview" href="#heading-event-handling-in-the-dom">Event Handling in the DOM</a><br>– <a class="post-section-overview" href="#heading-common-types-of-events">Common Types of Events</a><br>– <a class="post-section-overview" href="#heading-event-handlers">Event Handlers</a><br>– <a class="post-section-overview" href="#heading-event-propagation">Event Propagation</a><br>– <a class="post-section-overview" href="#heading-event-bubbling">Event Bubbling</a><br>– <a class="post-section-overview" href="#heading-event-delegation">Event Delegation</a></li>
<li><a class="post-section-overview" href="#heading-conclusion">Conclusion</a></li>
</ol>
<h2 id="heading-what-is-the-browser-object-model-bom">What is the Browser Object Model (BOM)?</h2>
<p>The Browser Object Model is like a set of tools provided by the browser itself. It's not part of the official DOM specification, but it's specific to web browsers. As a result, the objects and methods available in the BOM may vary between different browsers.</p>
<p>The BOM provides JavaScript access to browser-specific things like the browser's history, location, and browser window itself.</p>
<h3 id="heading-window-object">Window Object</h3>
<p>The <code>window</code> Object serves as a global object in the browser, representing the browser window and is the top-level object in JavaScript when we're working in a web browser. You can access it by typing <code>window</code> in the browser console:</p>
<pre><code class="lang-javascript"><span class="hljs-built_in">console</span>.log(<span class="hljs-built_in">window</span>); <span class="hljs-comment">// prints the Window object</span>
</code></pre>
<p>Since, it's global, you can access it from anywhere and use it to access other global objects such as the console and the alert function.</p>
<p>The <code>window</code> object is a key part of the BOM and provides access to many browser-related things. For example, <code>window.location.href</code> gives you the URL of the current web page.</p>
<p>Functions like <code>alert()</code>, <code>prompt()</code>, and <code>confirm()</code> are also part of the BOM, allowing you to interact with users through pop-up dialogs.</p>
<h2 id="heading-what-is-the-document-object-model-dom">What is the Document Object Model (DOM)?</h2>
<p>The Document Object Model (DOM) is a programming interface for web documents. It represents the structure of a web page, allowing interaction with its elements using programming languages like JavaScript.</p>
<p>The DOM contains the <code>document</code> object, which represents the DOM structure of the current web page and has properties and methods that allow you to manipulate the DOM.</p>
<p>You can access the <code>document</code> object by typing <code>document</code> in the browser console:</p>
<pre><code class="lang-javascript"><span class="hljs-built_in">console</span>.log(<span class="hljs-built_in">document</span>); <span class="hljs-comment">// prints the DOM object</span>
</code></pre>
<p>You use <code>document</code> object to access and manipulate different parts of the HTML document. Elements within the DOM can be accessed using properties and methods of this object.</p>
<p>Examples include accessing the <code>body</code> or <code>title</code> element, retrieving HTML content (<code>innerHTML</code>), accessing text content (<code>innerText</code>) and changing <code>styles</code>.</p>
<pre><code class="lang-javascript"><span class="hljs-comment">// Accessing the document's title</span>
<span class="hljs-built_in">console</span>.log(<span class="hljs-built_in">document</span>.title);

<span class="hljs-comment">// Changing the document's title</span>
<span class="hljs-built_in">document</span>.title = <span class="hljs-string">"changed Title"</span>;

<span class="hljs-comment">// Accessing the document's body </span>
<span class="hljs-built_in">console</span>.log(<span class="hljs-built_in">document</span>.body);
</code></pre>
<pre><code class="lang-javascript"><span class="hljs-comment">// Changing background color of body element using inline CSS</span>
<span class="hljs-built_in">document</span>.body.style.backgroundColor = <span class="hljs-string">"red"</span>;
</code></pre>
<p>You can use the DOM to interact with web pages dynamically. This allows JavaScript to access, modify, and manipulate the content, structure, and style of a web document in response to user actions or other events. </p>
<p>Let's illustrate the concept of DOM manipulation with a simple example:</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">html</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">body</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"container"</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">p</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"message"</span>&gt;</span>Hello, World!<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"changeText"</span>&gt;</span>Change Text<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>

    <span class="hljs-tag">&lt;<span class="hljs-name">script</span>&gt;</span><span class="javascript">
      <span class="hljs-comment">// we select the paragraph element by its ID</span>
      <span class="hljs-keyword">let</span> messageElement = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">"message"</span>);

      <span class="hljs-comment">// let's add event listener to button element using ID</span>
      <span class="hljs-built_in">document</span>
        .getElementById(<span class="hljs-string">"changeText"</span>)
        .addEventListener(<span class="hljs-string">"click"</span>, <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>{
          <span class="hljs-comment">// this  will change the text content of the paragraph element</span>
          messageElement.textContent = <span class="hljs-string">"Text Changed!"</span>;
        });
    </span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">body</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">html</span>&gt;</span>
</code></pre>
<p>In this example, we have an HTML document with a <code>&lt;div&gt;</code> container containing a <code>&lt;p&gt;</code> element and a <code>&lt;button&gt;</code> element. </p>
<p>Using JavaScript, we can select the <code>&lt;p&gt;</code> element by its ID and attach an event listener to the <code>&lt;button&gt;</code> element. When the button is clicked, the text content of the paragraph element is changed dynamically.</p>
<h2 id="heading-dom-tree-structure">DOM Tree Structure</h2>
<p>The DOM represents the layout of HTML and XML documents as a tree-like structure, resembling the hierarchical arrangement of elements on a web page. In this tree, each node represents a part of the document, such as HTML elements, attributes, and text.</p>
<p>The top-level node in the tree is called the <strong>document node</strong>, which represents the entire HTML document. From there, it branches out to include all elements and their relationships within the document. Here's a visual representation of that:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/02/pic_htmltree-1.gif" alt="Image" width="600" height="400" loading="lazy">
<em>DOM Tree of Objects</em></p>
<h3 id="heading-types-of-nodes-in-the-dom-tree">Types of Nodes in the DOM Tree</h3>
<p>There are two main types of nodes in the DOM:</p>
<ol>
<li><strong>Element Nodes:</strong> Represent HTML elements such as <code>&lt;div&gt;</code>, <code>&lt;h1&gt;</code>, <code>&lt;p&gt;</code>, <code>&lt;span&gt;</code>, and so on. These nodes make up the backbone of the DOM tree and form the structure of the HTML document.</li>
<li><strong>Text Nodes:</strong> Represent text content within HTML elements. Text always serves as the last child (leaf node) of an element node and cannot contain any child nodes.</li>
</ol>
<p>In HTML, whitespace such as spaces, tabs, and line breaks are considered part of the text content within HTML elements and are represented as <strong>text nodes</strong>.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/02/image-62.png" alt="Image" width="600" height="400" loading="lazy">
<em>Linebreak is 1st child node, div (Blue) is 2nd, linebreak again 3rd</em></p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/02/image-64.png" alt="Image" width="600" height="400" loading="lazy">
<em>We can see all the nodes here including non-element ones (like text nodes or comment nodes)</em></p>
<p>We also have:</p>
<ul>
<li><strong>Attribute Nodes:</strong> Represent attributes of HTML elements, for example <code>id</code>, <code>class</code>, <code>src</code>, <code>href</code>, and so on.</li>
<li><strong>Comment Nodes:</strong> Nodes representing comments within the HTML markup.</li>
</ul>
<p>To access and manipulate DOM elements, we can "walk" through the tree structure using JavaScript. For instance:</p>
<ul>
<li><code>document.head</code>: Selects the <code>&lt;head&gt;</code> element of the current HTML document.</li>
<li><code>document.body</code>: Selects the <code>&lt;body&gt;</code> element of the current HTML document.</li>
<li><code>document.documentElement</code>: Selects the root element of the DOM tree, that is <code>&lt;html&gt;</code>.</li>
</ul>
<p>Once we access an element, we can modify its attributes or properties accordingly. For example, we can alter the background color of the <code>&lt;body&gt;</code> element to red by executing <code>document.body.style.backgroundColor = "red"</code> in the console.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/02/image-80.png" alt="Image" width="600" height="400" loading="lazy">
<em>We can see the body color has changed to "red"</em></p>
<h3 id="heading-node-relationships">Node Relationships</h3>
<p>Nodes in the DOM tree have parent-child relationships, which form the hierarchical structure of the tree. A child is an element that directly resides within another element (the parent).</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"container"</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>Hello, World!<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">button</span>&gt;</span>Click Me<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
</code></pre>
<p>In the DOM tree, sibling elements are arranged linearly. The element to the right of the current element is called the next sibling, while the element to the left is called the previous sibling.</p>
<p>In the above example, the <code>&lt;p&gt;</code> element (previous sibling of ) and the <code>&lt;button&gt;</code> element (next sibling of </p><p>) are <strong>sibling nodes</strong> as they share the same parent. They are both <strong>children nodes</strong> of the <code>&lt;div&gt;</code> element with the ID "container". So the <code>&lt;div&gt;</code> element serves as the <strong>parent node</strong> of both the <code>&lt;p&gt;</code> and <code>&lt;button&gt;</code> elements.</p>
<p>Elements positioned above a given element in the DOM tree hierarchy are called ancestors. In the given code, the <code>&lt;html&gt;</code> element acts as the <strong>ancestor</strong> of the <code>&lt;body&gt;</code>, <code>&lt;h1&gt;</code>, and <code>&lt;p&gt;</code> elements, and they are <strong>descendants</strong> of the <code>&lt;html&gt;</code> element.</p>
<h2 id="heading-how-to-work-with-dom-elements">How to Work with DOM Elements</h2>
<p>Now, let's dive into accessing nodes in the DOM using various properties and methods.</p>
<h3 id="heading-traversing-the-dom">Traversing the DOM:</h3>
<p>When working with the Document Object Model (DOM), it's important to understand the distinction between element nodes (HTML elements) and non-element nodes (like text nodes, comments, and so on). Certain properties and methods specifically deal with either element nodes or all types of nodes, including non-element nodes.</p>
<p><strong>NodeList vs. HTMLCollection:</strong> Different properties return different collections of nodes. NodeList contains all types of nodes, while HTMLCollection specifically holds element nodes. Understanding this distinction is crucial for interpreting the results.</p>
<p><strong>Properties for All Nodes (Including Non-element Nodes):</strong> These properties return nodes of all types, including element nodes, text nodes, and comment nodes. </p>
<p><code>childNodes</code> returns a NodeList containing all child nodes and the <code>parentNode</code> property returns the parent node of the specified node. For example:</p>
<pre><code class="lang-javascript"><span class="hljs-comment">// Access the first child of the body node</span>
<span class="hljs-built_in">console</span>.log(<span class="hljs-built_in">document</span>.body.childNodes[<span class="hljs-number">0</span>]);


<span class="hljs-comment">// parentnode; the parent of a &lt;p&gt; element within a &lt;div&gt; would be the &lt;div&gt; itself.</span>
<span class="hljs-keyword">let</span> p = <span class="hljs-built_in">document</span>.querySelector(<span class="hljs-string">'p'</span>); <span class="hljs-comment">// Select the &lt;p&gt; element</span>
<span class="hljs-built_in">console</span>.log(p.parentNode); <span class="hljs-comment">// Output: &lt;div&gt; element (parent of p);</span>
</code></pre>
<p>Spaces between tags and line returns in HTML code are considered text nodes by the browser. So, the actual first child node might not be what you expect.</p>
<p><code>firstChild</code>/<code>lastChild</code>: Returns the first/last child node, again including all types.</p>
<pre><code class="lang-javascript"><span class="hljs-built_in">document</span>.body.firstChild; <span class="hljs-comment">// Outputs: First child node (likely a linebreak(text node))</span>
<span class="hljs-built_in">document</span>.body.lastChild; <span class="hljs-comment">// Outputs: Last child node (likely a script tag)</span>
</code></pre>
<p>So we can say the following:</p>
<pre><code class="lang-javascript">element.childNodes[<span class="hljs-number">0</span>] === element.firstChild;
element.childNodes[element.childNodes.length - <span class="hljs-number">1</span>] === element.lastChild;
</code></pre>
<p><code>nextSibling</code>/<code>previousSibling</code>: returns the next sibling/previous sibling node,  including all of them.</p>
<p><strong>Element specific properties or Element only navigation</strong>: These properties provide a convenient way to access only element nodes, excluding text nodes and comments.</p>
<p><code>children</code> returns a live HTMLCollection of direct child elements, and the <code>parentElement</code> property returns the parent element node of the specified node.</p>
<p>In the below screenshot, you can see the difference between <code>childNodes</code> and <code>children</code>:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/02/image-62.png" alt="Image" width="600" height="400" loading="lazy">
<em>Here, Linebreak (text node) will be considered 1st child node of body element, whereas div.color (Blue) will be considered the 1st child.</em></p>
<p>For instance, let's say we have this code:</p>
<pre><code class="lang-javascript"><span class="hljs-comment">// childnode</span>
<span class="hljs-built_in">console</span>.log(<span class="hljs-built_in">document</span>.body.childNodes);

<span class="hljs-comment">// children</span>
<span class="hljs-built_in">console</span>.log(<span class="hljs-built_in">document</span>.body.children);
</code></pre>
<pre><code><span class="hljs-comment">// childnode</span>
NodeList(<span class="hljs-number">19</span>) [text, div.color, text, div.color, text, comment, text, div.color, text, div.color, text, div.color, text, script, text, comment, text, script, text]


<span class="hljs-comment">// children</span>
HTMLCollection(<span class="hljs-number">7</span>) [div.color, div.color, div.color, div.color, div.color, script, script]
</code></pre><p>and, if we refresh the page, the output gets:</p>
<pre><code>NodeList(<span class="hljs-number">14</span>) [text, div.color, text, div.color, text, comment, text, div.color, text, div.color, text, div.color, text, script]
HTMLCollection(<span class="hljs-number">6</span>) [div.color, div.color, div.color, div.color, div.color, script]
</code></pre><p>Initially, the <code>NodeList</code> contains 19 nodes. These nodes consist of text nodes, <code>div</code> elements with the class "color", a comment node, and <code>script</code> elements. The <code>HTMLCollection</code> contains 7 elements, which are the <code>div</code> elements with the class "color" and <code>script</code> elements.</p>
<p>When the page is refreshed, some elements or nodes are removed or modified dynamically through JavaScript or other means, leading to the observed changes in the DOM structure.</p>
<p><code>firstElementChild</code>/<code>lastElementChild</code> returns the first/last child, excluding non-element nodes.</p>
<pre><code class="lang-javascript"><span class="hljs-comment">// Both will exclude text nodes and comment nodes.</span>
<span class="hljs-built_in">document</span>.body.firstElementChild; <span class="hljs-comment">// Outputs: &lt;div class="color"&gt;</span>
<span class="hljs-built_in">document</span>.body.lastElementChild; <span class="hljs-comment">// Outputs: &lt;script src="script.js"&gt;</span>
</code></pre>
<p><strong>Key Points:</strong></p>
<ul>
<li>Choose the right property based on whether you need to target all nodes or specifically element nodes.</li>
<li>Remember that properties like <code>firstChild</code> and <code>previousSibling</code> might return element and non-element nodes, while their element-specific counterparts (<code>firstElementChild</code> and <code>previousElementSibling</code>) focus only on elements.</li>
</ul>
<h3 id="heading-methods-for-querying-dom-elements">Methods for Querying DOM Elements:</h3>
<p>JavaScript provides several methods for accessing elements in the DOM:</p>
<ul>
<li><strong><code>getElementById</code>:</strong> This method retrieves an element by its unique ID attribute.</li>
</ul>
<pre><code class="lang-javascript"><span class="hljs-keyword">let</span> element = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">"myElement"</span>);
</code></pre>
<ul>
<li><strong><code>getElementsByClassName</code>:</strong> This method returns a collection of elements with the specified class name.</li>
</ul>
<pre><code class="lang-javascript"><span class="hljs-keyword">let</span> elements = <span class="hljs-built_in">document</span>.getElementsByClassName(<span class="hljs-string">"myClass"</span>);
</code></pre>
<ul>
<li><strong><code>getElementsByTagName</code>:</strong> This method returns a list of collection of elements with the specified tag name.</li>
</ul>
<pre><code class="lang-javascript"><span class="hljs-keyword">let</span> elements = <span class="hljs-built_in">document</span>.getElementsByTagName(<span class="hljs-string">"div"</span>);
</code></pre>
<ul>
<li><strong><code>querySelector</code>:</strong> This method retrieves the first element that matches a specified CSS selector.</li>
</ul>
<pre><code class="lang-javascript"><span class="hljs-keyword">let</span> element = <span class="hljs-built_in">document</span>.querySelector(<span class="hljs-string">"cssSelector"</span>);
</code></pre>
<ul>
<li><strong><code>querySelectorAll</code>:</strong>  This method retrieves all elements that match a CSS                 selector.</li>
</ul>
<pre><code class="lang-javascript"><span class="hljs-keyword">let</span> elements = <span class="hljs-built_in">document</span>.querySelectorAll(<span class="hljs-string">"cssSelector"</span>);
</code></pre>
<p>You might be wondering how <code>querySelector</code> differs from <code>querySelectorAll</code>.</p>
<p>Well, <code>querySelector</code> returns the first element within the document that matches the specified selector. On the other hand, <code>querySelectorAll</code> returns a static NodeList representing a list of the document's elements that match the specified group of selectors.</p>
<p>When you're using <code>querySelectorAll</code>, you receive a NodeList, which is similar to an array but not exactly the same. You cannot directly manupulate all elements like appling styles to all elements within a NodeList using methods like <code>style.backgroundColor = 'red'</code>. So we use a <code>forEach</code> loop. For example:</p>
<pre><code class="lang-javascript"><span class="hljs-built_in">console</span>.log(<span class="hljs-built_in">document</span>.querySelectorAll(<span class="hljs-string">".box"</span>));

<span class="hljs-built_in">document</span>.querySelectorAll(<span class="hljs-string">'.box'</span>).forEach(<span class="hljs-function"><span class="hljs-params">element</span> =&gt;</span> {
    <span class="hljs-comment">// Within the forEach loop, we access each element and set its background color to green.</span>
    element.style.backgroundColor = <span class="hljs-string">"green"</span>;
});
</code></pre>
<p>Let's see what's going on in this code:</p>
<ul>
<li>In the first line, we directly change the background color of the element with the class 'box' using querySelector.</li>
<li>In the second line, we use querySelectorAll to select all elements with the class 'box' and log the NodeList to the console.</li>
<li>In third line, since <code>querySelectorAll</code> returns a NodeList, we need to iterate through each element in the NodeList in order to apply the background color to each element separately.</li>
<li>so  basically, we can say <code>querySelector</code> is equivalent to <code>querySelectorAll('section')[0]</code>.</li>
</ul>
<p>Alright, one last method to consider:</p>
<ul>
<li><strong><code>getElementsByName</code></strong>: This method returns a list of collection of elements with the specified name attribute.</li>
</ul>
<pre><code class="lang-javascript"><span class="hljs-keyword">let</span> items = <span class="hljs-built_in">document</span>.getElementsByName(<span class="hljs-string">'some-name-attribute'</span>);
<span class="hljs-built_in">console</span>.log(items);
</code></pre>
<p>These methods are important to understand because they are used in various situations. </p>
<p>For example, when we want to select all the <code>div</code> elements in the document, we can use the <code>querySelectorAll</code> method or the <code>getElementsByTagName</code> method. Both methods will return the same result, but <code>querySelectorAll</code> is more flexible because it can select elements that match any CSS selector. <code>getElementsByTagName</code> can only select elements that have the same tag name.</p>
<h3 id="heading-matches-closest-and-contains">Matches, Closest, and Contains:</h3>
<p>When you're working with JavaScript and dealing with web pages, you often need to find specific parts of the page or do things with them. Three methods you might use are <code>matches()</code>, <code>closest()</code>, and <code>contains()</code>.</p>
<p><strong><code>matches()</code></strong> checks if an element matches a certain style rule. For example, if you have a button and you want to see if it has a class of "active", you could use <code>button.matches('.active')</code>. It will return true if the button has that class, and false if it doesn't.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> button = <span class="hljs-built_in">document</span>.querySelector(<span class="hljs-string">'button'</span>);
<span class="hljs-keyword">if</span> (button.matches(<span class="hljs-string">'.active'</span>)) {
  <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'The button is active'</span>);
} <span class="hljs-keyword">else</span> {
  <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'The button is not active'</span>);
}
</code></pre>
<p>If you have an element and you want to find its nearest parent with a certain class, you can use <code>**closest()**</code> like this: <code>element.closest('.classname')</code>. </p>
<p>For instance, if you have a  link inside a list item and you want to find the nearest list item, you could do <code>link.closest('li')</code>.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> link = <span class="hljs-built_in">document</span>.querySelector(<span class="hljs-string">'a'</span>);
<span class="hljs-keyword">const</span> listItem = link.closest(<span class="hljs-string">'li'</span>);
<span class="hljs-built_in">console</span>.log(listItem); <span class="hljs-comment">// This will give you the nearest list item</span>
</code></pre>
<p>And <strong><code>contains()</code></strong> checks if one element is inside another. For example, if you have a div and a paragraph inside it, you could check if the div contains the paragraph with <code>div.contains(paragraph)</code>. It will return true if the paragraph is inside the div, and false if it's not.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> div = <span class="hljs-built_in">document</span>.querySelector(<span class="hljs-string">'div'</span>);
<span class="hljs-keyword">const</span> paragraph = <span class="hljs-built_in">document</span>.querySelector(<span class="hljs-string">'p'</span>);
<span class="hljs-keyword">if</span> (div.contains(paragraph)) {
  <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'The div contains a paragraph'</span>);
} <span class="hljs-keyword">else</span> {
  <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'The div does not contain any paragraph'</span>);
}
</code></pre>
<p>These methods are handy for navigating around your web page and doing different things with its elements.</p>
<h3 id="heading-how-to-inspect-dom-elements">How to Inspect DOM Elements</h3>
<p><strong>Using console.dir():</strong> <code>console.dir()</code> is not a method of the DOM. It's a method provided by the browser's Console API, specifically used for logging JavaScript objects to the console.</p>
<p>If we log an element using <code>console.log()</code>, we see its HTML representation. But with <code>console.dir()</code>, we get an interactive list showing all available attributes and functions for that element.</p>
<p><strong><code>tagName</code></strong> and <code>nodeName</code>: <code>tagName</code> is a property specific to HTML elements. It returns the tag name of an HTML element in uppercase letters. For example, if you have an HTML element <code>&lt;div&gt;</code>, <code>tagName</code> will return <code>"DIV"</code>.</p>
<p>On the other hand, <code>nodeName</code> is a property of DOM nodes that represents the name of the node. For element nodes, it returns the tag name in uppercase. For other types of nodes, it returns a string representing the type of node (for example, "#text" for text nodes, "#comment" for comment nodes).</p>
<p><strong>Discovering a node's type:</strong> Each node in the DOM has a <code>nodeType</code> property that indicates its type. It has a numeric value: <code>1</code> for elements, <code>2</code> for attributes, <code>3</code> for text nodes, <code>8</code> for comment and <code>9</code> for document. Read-only. This property can be used to distinguish between element nodes and text nodes. For example:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> element = <span class="hljs-built_in">document</span>.createElement(<span class="hljs-string">'div'</span>);
<span class="hljs-built_in">console</span>.log(element.nodeType); <span class="hljs-comment">// Output: 1</span>
</code></pre>
<h3 id="heading-table-navigation-in-the-dom">Table Navigation in the DOM</h3>
<p>Now, let's learn how to navigate a table element and its child nodes using the DOM. Here, instead of manually writing a table, we will use Bootstrap's pre-designed table.</p>
<p>Before diving into table navigation, let's discuss Bootstrap, a popular front-end framework offering pre-designed components and styles for building responsive web pages efficiently.</p>
<p>To integrate Bootstrap into our project, we'll:</p>
<ol>
<li>Copy the pre-designed table from <a target="_blank" href="https://getbootstrap.com/docs/5.3/content/tables/">here</a>.</li>
<li>Paste it into a container <code>&lt;div&gt;</code> in our HTML.</li>
<li>Include Bootstrap's CSS and JS files in our webpage (which you can copy from <a target="_blank" href="https://getbootstrap.com/docs/5.3/getting-started/introduction/">here</a>).</li>
</ol>
<p>Here's how our HTML code will look after integration:</p>
<pre><code class="lang-html"><span class="hljs-meta">&lt;!DOCTYPE <span class="hljs-meta-keyword">html</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">html</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">head</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">title</span>&gt;</span>Table Navigation<span class="hljs-tag">&lt;/<span class="hljs-name">title</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">link</span> <span class="hljs-attr">rel</span>=<span class="hljs-string">"stylesheet"</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"styles.css"</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">link</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha3/dist/css/bootstrap.min.css"</span> <span class="hljs-attr">rel</span>=<span class="hljs-string">"stylesheet"</span> <span class="hljs-attr">integrity</span>=<span class="hljs-string">"sha384-KK94CHFLLe+nY2dmCWGMq91rCGa5gtU4mk92HdvYe+M/SXH301p5ILy+dN9+nJOZ"</span> <span class="hljs-attr">crossorigin</span>=<span class="hljs-string">"anonymous"</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">head</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">body</span>&gt;</span>
   <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"container"</span>&gt;</span>
    <span class="hljs-comment">&lt;!-- Bootstrap Table --&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">table</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"table"</span>&gt;</span>
        <span class="hljs-comment">&lt;!-- Table Header --&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">thead</span>&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">tr</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">th</span> <span class="hljs-attr">scope</span>=<span class="hljs-string">"col"</span>&gt;</span>#<span class="hljs-tag">&lt;/<span class="hljs-name">th</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">th</span> <span class="hljs-attr">scope</span>=<span class="hljs-string">"col"</span>&gt;</span>First<span class="hljs-tag">&lt;/<span class="hljs-name">th</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">th</span> <span class="hljs-attr">scope</span>=<span class="hljs-string">"col"</span>&gt;</span>Last<span class="hljs-tag">&lt;/<span class="hljs-name">th</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">th</span> <span class="hljs-attr">scope</span>=<span class="hljs-string">"col"</span>&gt;</span>Handle<span class="hljs-tag">&lt;/<span class="hljs-name">th</span>&gt;</span>
          <span class="hljs-tag">&lt;/<span class="hljs-name">tr</span>&gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-name">thead</span>&gt;</span>
        <span class="hljs-comment">&lt;!-- Table Body --&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">tbody</span>&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">tr</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">th</span> <span class="hljs-attr">scope</span>=<span class="hljs-string">"row"</span>&gt;</span>1<span class="hljs-tag">&lt;/<span class="hljs-name">th</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">td</span>&gt;</span>Mark<span class="hljs-tag">&lt;/<span class="hljs-name">td</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">td</span>&gt;</span>Otto<span class="hljs-tag">&lt;/<span class="hljs-name">td</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">td</span>&gt;</span>@mdo<span class="hljs-tag">&lt;/<span class="hljs-name">td</span>&gt;</span>
          <span class="hljs-tag">&lt;/<span class="hljs-name">tr</span>&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">tr</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">th</span> <span class="hljs-attr">scope</span>=<span class="hljs-string">"row"</span>&gt;</span>2<span class="hljs-tag">&lt;/<span class="hljs-name">th</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">td</span>&gt;</span>Jacob<span class="hljs-tag">&lt;/<span class="hljs-name">td</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">td</span>&gt;</span>Thornton<span class="hljs-tag">&lt;/<span class="hljs-name">td</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">td</span>&gt;</span>@fat<span class="hljs-tag">&lt;/<span class="hljs-name">td</span>&gt;</span>
          <span class="hljs-tag">&lt;/<span class="hljs-name">tr</span>&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">tr</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">th</span> <span class="hljs-attr">scope</span>=<span class="hljs-string">"row"</span>&gt;</span>3<span class="hljs-tag">&lt;/<span class="hljs-name">th</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">td</span> <span class="hljs-attr">colspan</span>=<span class="hljs-string">"2"</span>&gt;</span>Larry the Bird<span class="hljs-tag">&lt;/<span class="hljs-name">td</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">td</span>&gt;</span>@twitter<span class="hljs-tag">&lt;/<span class="hljs-name">td</span>&gt;</span>
          <span class="hljs-tag">&lt;/<span class="hljs-name">tr</span>&gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-name">tbody</span>&gt;</span>
      <span class="hljs-tag">&lt;/<span class="hljs-name">table</span>&gt;</span>
   <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"script.js"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha3/dist/js/bootstrap.bundle.min.js"</span> <span class="hljs-attr">integrity</span>=<span class="hljs-string">"sha384-ENjdO4Dr2bkBIFxQpeoTz1HIcje39Wm4jDKdf19U8gI4ddQ3GYNS7NTKfAdVQSZe"</span> <span class="hljs-attr">crossorigin</span>=<span class="hljs-string">"anonymous"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">body</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">html</span>&gt;</span>
</code></pre>
<h4 id="heading-table-navigation-properties">Table navigation properties:</h4>
<p>The table element supports various properties for convenient navigation, such as:</p>
<ul>
<li><code>table.rows</code>: Returns an HTMLCollection of all rows in the table.</li>
<li><code>table.caption</code>: Returns the caption element of the table.</li>
<li><code>table.tHead</code>: Returns the thead element of the table.</li>
<li><code>table.tFoot</code>: Returns the tfoot element of the table.</li>
<li><code>table.tBodies</code>: Returns an HTMLCollection of all tbody elements in the table.</li>
</ul>
<p>Similarly, the tr (table row) element supports properties like:</p>
<ul>
<li><code>tr.cells</code>: Returns an HTMLCollection of all cells in the row.</li>
<li><code>tr.sectionRowIndex</code>: Returns the index of the row in the current section (thead, tbody, or tfoot).</li>
<li><code>tr.rowIndex</code>: Returns the index of the row in the table.</li>
</ul>
<p>The td (table cell) element also supports the <code>td.cellIndex</code> property, returning the index of the cell in the row.</p>
<p>For instance, to print all rows in the table:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">let</span> t = <span class="hljs-built_in">document</span>.body.firstElementChild.firstElementChild; <span class="hljs-comment">// Selecting the table</span>
<span class="hljs-keyword">for</span> (<span class="hljs-keyword">let</span> i = <span class="hljs-number">0</span>; i &lt; t.rows.length; i++) {
    <span class="hljs-keyword">let</span> row = t.rows[i];
    <span class="hljs-built_in">console</span>.log(row)
}
</code></pre>
<p>To print cells in the first row:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">let</span> t = <span class="hljs-built_in">document</span>.body.firstElementChild.firstElementChild; <span class="hljs-comment">// Selecting the table</span>
<span class="hljs-keyword">let</span> row = t.rows[<span class="hljs-number">0</span>]; <span class="hljs-comment">// Selecting the first row</span>
<span class="hljs-keyword">for</span> (<span class="hljs-keyword">let</span> i = <span class="hljs-number">0</span>; i &lt; row.cells.length; i++) {
    <span class="hljs-keyword">let</span> cell = row.cells[i];
    <span class="hljs-built_in">console</span>.log(cell)
}
</code></pre>
<h2 id="heading-how-to-modify-dom-elements">How to Modify DOM Elements</h2>
<p>Once you have access to DOM elements, you can modify them in various ways using JavaScript.</p>
<h3 id="heading-how-to-manipulate-element-content-and-visibility">How to Manipulate Element Content and Visibility</h3>
<h4 id="heading-innerhtml-and-outerhtml"><code>innerHTML</code> and <code>outerHTML</code></h4>
<p>You can use <code>innerHTML</code> to access or change the HTML content inside an element as a string. <code>outerHTML</code>, on the other hand, lets you get or set the HTML content of an element as a string, including the original element itself.</p>
<p>Here's an example:</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">body</span>&gt;</span>
    Hello World
    <span class="hljs-tag">&lt;<span class="hljs-name">span</span>&gt;</span>Hey I am span<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"script.js"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">body</span>&gt;</span>
</code></pre>
<pre><code class="lang-javascript"><span class="hljs-keyword">let</span> first = <span class="hljs-built_in">document</span>.getElementsByTagName(<span class="hljs-string">"span"</span>)[<span class="hljs-number">0</span>]; <span class="hljs-comment">// </span>

<span class="hljs-comment">// log and change inner HTML</span>
<span class="hljs-built_in">console</span>.log(first.innerHTML); <span class="hljs-comment">// Output: Hey I am span</span>
first.innerHTML = <span class="hljs-string">"Hey I am changed"</span>; <span class="hljs-comment">// Modify the content of the &lt;span&gt; element</span>

<span class="hljs-comment">// log and change outer HTML</span>
<span class="hljs-built_in">console</span>.log(first.outerHTML); <span class="hljs-comment">// Output: &lt;span&gt;Hey I am span&lt;/span&gt;</span>
first.outerHTML = <span class="hljs-string">"&lt;h1&gt;Hey I am changed&lt;/h1&gt;"</span>; <span class="hljs-comment">// Reload the page to see the change</span>
</code></pre>
<h4 id="heading-textcontent-property"><code>textContent</code> property</h4>
<p>The <code>textContent</code> property allows you to set or retrieve the text content of an element, ignoring any HTML tags within it. It's useful when you want to update the text content of an element without affecting its HTML structure.</p>
<pre><code class="lang-javascript"><span class="hljs-built_in">console</span>.log(first.textContent); <span class="hljs-comment">// output: Hey I am span</span>

<span class="hljs-comment">// change the text content</span>
first.textContent = <span class="hljs-string">"Hey I am changed"</span>;
</code></pre>
<h4 id="heading-innertext-property"><code>innerText</code> property</h4>
<p>The <code>innerText</code> property returns only the visible text content of an element, excluding any text within <code>&lt;script&gt;</code> and <code>&lt;style&gt;</code> elements, and accounting for CSS styling that affects visibility. It takes into account CSS styling, such as <code>display: none</code>, <code>visibility: hidden</code>, and so on and returns only the text that is rendered on the screen. </p>
<h4 id="heading-style-property"><code>style</code> property</h4>
<p>This property provides access to an object for manipulating an element's inline styles (for example, <code>element.style.color = "red"</code>).</p>
<h4 id="heading-hidden-property"><code>hidden</code> property</h4>
<p>The <code>hidden</code> provides a simple and convenient way to control the visibility of elements in the DOM without directly manipulating their style properties.</p>
<pre><code class="lang-javascript"><span class="hljs-built_in">document</span>.getElementsByTagName(<span class="hljs-string">'span'</span>)[<span class="hljs-number">0</span>].hidden = <span class="hljs-literal">true</span>;

<span class="hljs-comment">// When hidden is set to false, the element is visible.</span>
</code></pre>
<p>Note that setting an element's <code>hidden</code> property to <code>true</code> only hides it from view, but it still occupies space in the document layout. </p>
<h3 id="heading-how-to-modify-element-attributes">How to Modify Element Attributes</h3>
<p>The <code>getAttribute()</code> method retrieves the value of a specified attribute of an element, while <code>setAttribute()</code> sets or updates the value of a specified attribute. </p>
<p><code>hasAttribute()</code> checks whether an element has a specific attribute, returning true or false. The <code>removeAttribute()</code> method removes a specified attribute from an element.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/02/image-68.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>In HTML5, it's possible to define custom attributes for elements. But to prevent potential conflicts with future HTML or JavaScript updates, you should prefix custom attributes with <code>data-</code>. For instance:</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"element1"</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"sample"</span> <span class="hljs-attr">data-category</span>=<span class="hljs-string">"music"</span> <span class="hljs-attr">data-rating</span>=<span class="hljs-string">"5"</span>&gt;</span>
    This is the first element.
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
</code></pre>
<p>To access these custom attributes using JavaScript, we can utilize the <code>dataset</code> property. For example:</p>
<pre><code class="lang-javascript"><span class="hljs-built_in">console</span>.log(element1.dataset);
</code></pre>
<p>This will display a <code>DOMStringMap</code> object containing all the custom attributes associated with the "element1" div. Specific custom attributes can also be accessed by their names. For example:</p>
<pre><code class="lang-javascript"><span class="hljs-built_in">console</span>.log(element1.dataset.category);

<span class="hljs-comment">// This code would output the value of the "category" custom attribute, which in this case is "music"</span>
</code></pre>
<h3 id="heading-html-insertion-methods">HTML Insertion Methods</h3>
<p>In HTML, there are several ways to insert new content or modify existing content dynamically using JavaScript. These are known as HTML insertion methods. </p>
<p>Consider the following HTML as our example:</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">html</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">head</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">head</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">body</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"container"</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"first"</span>&gt;</span>first element<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"script.js"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">body</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">html</span>&gt;</span>
</code></pre>
<h4 id="heading-classic-way-to-insert-html">Classic Way to Insert HTML:</h4>
<p>A conventional way to insert HTML is by using the <code>innerHTML</code> property. For example, let's say we want to add an <code>h1</code> element with the text "Hello World" inside the first <code>div</code>. We can do this using the following code:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">let</span> a = <span class="hljs-built_in">document</span>.getElementsByTagName(<span class="hljs-string">'div'</span>)[<span class="hljs-number">0</span>];
a.innerHTML = <span class="hljs-string">'&lt;h1&gt;Hello World&lt;/h1&gt;'</span>;
</code></pre>
<p>We could also append new HTML to the existing HTML inside the <code>div</code> element. For example:</p>
<pre><code class="lang-javascript"><span class="hljs-comment">// This will retain the old content and add a new h1 element.</span>
<span class="hljs-keyword">let</span> a = <span class="hljs-built_in">document</span>.getElementsByTagName(<span class="hljs-string">'div'</span>)[<span class="hljs-number">0</span>];
a.innerHTML = a.innerHTML + <span class="hljs-string">'&lt;h1&gt;Hello World&lt;/h1&gt;'</span>;
</code></pre>
<h4 id="heading-using-createelement-to-insert-html">Using <code>createElement</code> to Insert HTML:</h4>
<p>Another method involves creating a new element using <code>createElement</code>, setting its content using <code>innerHTML</code>, and subsequently appending it to the target element using <code>appendChild</code>.</p>
<h4 id="heading-other-html-insertion-methods">Other HTML Insertion Methods:</h4>
<pre><code class="lang-html"><span class="hljs-meta">&lt;!DOCTYPE <span class="hljs-meta-keyword">html</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">html</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">head</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">head</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">body</span>&gt;</span>
I am outside div (start)
<span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"container"</span>&gt;</span>
    I am start of this container
        <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"first"</span>&gt;</span>I am first element<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
    I am end of this container
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
I am outside div (end)
    <span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"script.js"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">body</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">html</span>&gt;</span>
</code></pre>
<p>Now, let's consider other methods for inserting HTML content dynamically:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">let</span> a = <span class="hljs-built_in">document</span>.getElementsByTagName(<span class="hljs-string">'div'</span>)[<span class="hljs-number">0</span>];

<span class="hljs-comment">// Using createElement and appendChild</span>
<span class="hljs-keyword">let</span> div = <span class="hljs-built_in">document</span>.createElement(<span class="hljs-string">'div'</span>);
div.innerHTML = <span class="hljs-string">'&lt;h1&gt;Hello World (append)&lt;/h1&gt;'</span>;
a.appendChild(div);

<span class="hljs-comment">// Using prepend</span>
<span class="hljs-keyword">let</span> div = <span class="hljs-built_in">document</span>.createElement(<span class="hljs-string">'div'</span>);
div.innerHTML = <span class="hljs-string">'&lt;h1&gt;Hello World (prepend)&lt;/h1&gt;'</span>;
a.prepend(div);

<span class="hljs-comment">// Using before</span>
<span class="hljs-keyword">let</span> div = <span class="hljs-built_in">document</span>.createElement(<span class="hljs-string">'div'</span>);
div.innerHTML = <span class="hljs-string">'&lt;h1&gt;Hello World (before)&lt;/h1&gt;'</span>;
a.before(div);

<span class="hljs-comment">// Using after</span>
<span class="hljs-keyword">let</span> div = <span class="hljs-built_in">document</span>.createElement(<span class="hljs-string">'div'</span>);
div.innerHTML = <span class="hljs-string">'&lt;h1&gt;Hello World (after)&lt;/h1&gt;'</span>;
a.after(div);

<span class="hljs-comment">// Using replaceWith</span>
<span class="hljs-keyword">let</span> div = <span class="hljs-built_in">document</span>.createElement(<span class="hljs-string">'div'</span>);
div.innerHTML = <span class="hljs-string">'&lt;h1&gt;Hello World (replaced)&lt;/h1&gt;'</span>;
a.replaceWith(div);
</code></pre>
<p>This code demonstrates different methods for dynamically inserting HTML content into the DOM using JavaScript.</p>
<ul>
<li><code>a.append(div)</code>: This method appends the <code>div</code> element as the last child of the <code>a</code> element.</li>
<li><code>a.prepend(div)</code>: This method adds the <code>div</code> element as the first child of the <code>a</code> element.</li>
<li><code>a.before(div)</code>: This method adds the <code>div</code> element before the <code>a</code> element.</li>
<li><code>a.after(div)</code>: This method adds the <code>div</code> element after the <code>a</code> element.</li>
<li><code>a.replaceWith(div)</code>: This method replaces the <code>a</code> element with the <code>div</code> element.</li>
</ul>
<h3 id="heading-the-insertadjacenthtml-insertadjacentelement-and-insertadjacenttext-methods">The <code>insertAdjacentHTML</code>, <code>insertAdjacentElement</code>, and <code>insertAdjacentText</code> Methods</h3>
<p>These methods are used to insert content into the DOM at a specified position relative to a given element. They are helpful when you need to dynamically add new elements or text to your webpage.</p>
<h4 id="heading-insertadjacenthtml"><code>insertAdjacentHTML</code>:</h4>
<p><code>insertAdjacentHTML</code> allows you to insert a string of HTML at a specified position relative to the element.</p>
<p>The first parameter specifies where the HTML string will be inserted:</p>
<ul>
<li><code>beforebegin</code>: Before the element itself.</li>
<li><code>afterbegin</code>: Just inside the element, before its first child.</li>
<li><code>beforeend</code>: Just inside the element, after its last child.</li>
<li><code>afterend</code>: After the element itself.</li>
</ul>
<p>Example usage:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">let</span> element = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">'example'</span>);
element.insertAdjacentHTML(<span class="hljs-string">'beforebegin'</span>, <span class="hljs-string">'&lt;div&gt;New content&lt;/div&gt;'</span>);
</code></pre>
<h4 id="heading-insertadjacentelement"><code>insertAdjacentElement</code>:</h4>
<p>It's similar to <code>insertAdjacentHTML</code>, but instead of inserting HTML, you can insert a DOM element.</p>
<p>Example usage:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">let</span> element = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">'example'</span>);
<span class="hljs-keyword">let</span> newElement = <span class="hljs-built_in">document</span>.createElement(<span class="hljs-string">'div'</span>);
newElement.textContent = <span class="hljs-string">'New content'</span>;
element.insertAdjacentElement(<span class="hljs-string">'beforebegin'</span>, newElement);
</code></pre>
<h4 id="heading-insertadjacenttext"><code>insertAdjacentText</code>:</h4>
<p>It's similar to <code>insertAdjacentHTML</code>, but instead of inserting HTML, you can insert plain text.</p>
<p>Example usage:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">let</span> element = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">'example'</span>);
element.insertAdjacentText(<span class="hljs-string">'beforebegin'</span>, <span class="hljs-string">'New content'</span>);
</code></pre>
<h4 id="heading-node-removal">Node Removal:</h4>
<p>The <code>remove</code> method removes the element from the DOM.</p>
<p>Example usage:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">let</span> element = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">'example'</span>);
element.remove();
</code></pre>
<p>These methods allow you to manipulate the DOM dynamically, adding or removing content based on certain conditions or user interactions.</p>
<p>When using <code>insertAdjacentHTML</code>, <code>insertAdjacentElement</code>, or <code>insertAdjacentText</code>, you specify where the new content should be inserted relative to the given element.</p>
<p>When using <code>remove</code>, you simply remove the element from the DOM entirely.</p>
<p>These methods are helpful for dynamically updating the content of your webpage without having to reload the entire page.</p>
<h3 id="heading-how-to-manipulate-classes-with-javascript">How to Manipulate Classes with JavaScript</h3>
<p>In HTML, we use classes to group elements and apply styles using CSS. For example, we have a div with an id of "first" in our HTML.</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"first"</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">span</span>&gt;</span>Hello, this is text<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
</code></pre>
<p>We also have CSS styles for classes like "yellow", "red", and "text-dark" to change background color and text color.</p>
<pre><code class="lang-css"><span class="hljs-selector-class">.yellow</span> {
    <span class="hljs-attribute">background-color</span>: yellow;
    <span class="hljs-attribute">color</span>: white;
}
<span class="hljs-selector-class">.red</span> {
    <span class="hljs-attribute">background-color</span>: red;
    <span class="hljs-attribute">color</span>: white;
}
<span class="hljs-selector-class">.text-dark</span> {
    <span class="hljs-attribute">color</span>: black;
}
</code></pre>
<p><strong><code>className</code>:</strong> In JavaScript, we can change the class of an element using the <code>className</code> property. For instance, if we want to change the class of the element with the id "first" to "red text-dark", we would do:</p>
<pre><code class="lang-javascript"><span class="hljs-comment">// we are applying 2 classes here</span>
first.className = <span class="hljs-string">"red text-dark"</span>;
</code></pre>
<p>If we want to add another class without removing the existing ones, we use the <code>+=</code> operator:</p>
<pre><code class="lang-javascript">first.className += <span class="hljs-string">" yellow"</span>; <span class="hljs-comment">// Adds the class "yellow" without removing existing classes</span>
</code></pre>
<p><strong><code>classList</code>:</strong> The <code>classList</code> property allows you to manipulate the classes of an element. We can use methods like <code>add</code>, <code>remove</code>, <code>toggle</code>, and <code>contains</code> to add, remove, toggle, or check the presence of a class.</p>
<ul>
<li><code>classList.remove()</code>: Removes a specific class from the element:</li>
</ul>
<pre><code class="lang-javascript">first.classList.remove(<span class="hljs-string">'text-dark'</span>); <span class="hljs-comment">// Removes the class "text-dark"</span>
</code></pre>
<ul>
<li><code>classList.add()</code>: But wait, it looked better with that class! We can also add it back with:</li>
</ul>
<pre><code class="lang-javascript">first.classList.add(<span class="hljs-string">'text-dark'</span>); <span class="hljs-comment">// Adds the class "text-dark"</span>
</code></pre>
<ul>
<li><code>classList.toggle()</code>: Toggles a class on or off based on its presence:</li>
</ul>
<pre><code class="lang-javascript">first.classList.toggle(<span class="hljs-string">'text-dark'</span>); <span class="hljs-comment">// Toggles the class "text-dark" (adds if absent, removes if present)</span>
</code></pre>
<ul>
<li><code>classList.contains()</code>: Checks if a class is present on the element:</li>
</ul>
<pre><code class="lang-javascript"><span class="hljs-built_in">console</span>.log(first.classList.contains(<span class="hljs-string">'text-dark'</span>)); <span class="hljs-comment">// Returns true if the class "text-dark" is present</span>
</code></pre>
<h2 id="heading-event-handling-in-the-dom">Event Handling in the DOM</h2>
<p>Events are actions or occurrences that happen in the system you are programming, that the system may need to respond to in some way. </p>
<p>In the context of web development, events (<strong>Browser Events</strong>) can be user interactions like clicks, mouse movements, key presses, and so on. JavaScript allows you to handle these events and perform actions in response to them.</p>
<p>In HTML, you can directly specify what should happen when an event occurs using attributes like <code>onclick</code>, <code>onmouseover</code>, and so on. For example:</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">onclick</span>=<span class="hljs-string">"alert('hello')"</span>&gt;</span>Click me<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
</code></pre>
<p>While you can write JavaScript directly in HTML attributes, it's always better to keep your HTML clean and handle events in JavaScript code separately. This makes your code easier to read and maintain.</p>
<p>You can do this by selecting elements from the webpage using JavaScript and then attaching an event handler to them. Here's how you might do it:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">let</span> container = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">"container"</span>);
container.onclick = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) </span>{
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"Hey, this is logged from the script!"</span>);
}
</code></pre>
<p>In this code, we select the element with the id "container" using <code>document.getElementById()</code>. Then, we attach a function to the <code>onclick</code> event of that element. This function will be executed whenever the element is clicked.</p>
<h3 id="heading-common-types-of-events">Common Types of Events:</h3>
<ol>
<li><p><strong>Mouse Events</strong>: These events are related to interactions with the mouse. </p>
</li>
<li><p><strong>click</strong>: When you click on an element.</p>
</li>
<li><strong>contextmenu</strong>: When you right-click on an element.</li>
<li><strong>mouseover / mouseout</strong>: When the mouse cursor enters or leaves an element.</li>
<li><strong>mousedown / mouseup</strong>: When you press or release a mouse button over an element.</li>
<li><strong>mousemove</strong>: When the mouse is moved.</li>
</ol>
<p>Some Examples of Mouse Events:</p>
<pre><code class="lang-javascript"><span class="hljs-comment">// Mouse Button Property Example:</span>

&lt;div onmousedown=<span class="hljs-string">"console.log('Mouse button:', event.button)"</span>&gt;Click me&lt;/div&gt;
</code></pre>
<p>In this example, the event.button property is used to log which mouse button was pressed.</p>
<pre><code class="lang-javascript"><span class="hljs-comment">// Modifier Keys Example:</span>

&lt;div onclick=<span class="hljs-string">"if(event.ctrlKey) console.log('Ctrl + Click!')"</span>&gt;Ctrl + Click Me&lt;/div&gt;
</code></pre>
<p>This example logs a message when the user clicks the element while holding the Ctrl key.</p>
<pre><code class="lang-javascript"><span class="hljs-comment">// Coordinates Example:</span>

&lt;div onmousemove=<span class="hljs-string">"console.log('clientX:', event.clientX, 'clientY:', event.clientY)"</span>&gt;Move your mouse here&lt;/div&gt;
</code></pre>
<p>This example logs the clientX and clientY coordinates of the mouse pointer as it moves over the element.</p>
<pre><code class="lang-javascript"><span class="hljs-comment">// Preventing Selection Example:</span>

&lt;span ondblclick=<span class="hljs-string">"console.log('Double clicked!')"</span> onmousedown=<span class="hljs-string">"return false;"</span>&gt;Double-click me&lt;/span&gt;
</code></pre>
<p>In this example, the return false statement in the onmousedown event handler prevents the default selection behavior when the element is double-clicked.</p>
<ol start="2">
<li><strong>Keyboard Events –</strong> <strong>keydown / keyup</strong>: When a key is pressed or released on the keyboard.</li>
</ol>
<p>Some Examples of Keyboard Events:</p>
<pre><code class="lang-javascript">&lt;input type=<span class="hljs-string">"text"</span> onkeydown=<span class="hljs-string">"console.log('Key pressed!')"</span> onkeyup=<span class="hljs-string">"console.log('Key released!')"</span>&gt;
</code></pre>
<p>In this example, the input field triggers events when a key is pressed (keydown) and released (keyup).</p>
<pre><code class="lang-javascript"><span class="hljs-comment">// Event Modifiers Example:</span>

&lt;input type=<span class="hljs-string">"text"</span> onkeydown=<span class="hljs-string">"if(event.ctrlKey &amp;&amp; event.key === 'c') console.log('Ctrl + C pressed!')"</span>&gt;
</code></pre>
<p>This example logs a message when the user presses the Ctrl key and 'c' key simultaneously in the input field.</p>
<pre><code class="lang-javascript"><span class="hljs-comment">// Accessing Key Information Example:</span>

&lt;input type=<span class="hljs-string">"text"</span> onkeydown=<span class="hljs-string">"console.log('Key pressed:', event.key)"</span>&gt;
</code></pre>
<p>This example logs the key that was pressed in the input field.</p>
<ol start="3">
<li><p><strong>Form Element Events</strong>: These events occur when you interact with form elements, like submitting a form, focusing on an input field, and so on.</p>
</li>
<li><p><strong>Document Events</strong>: These events are related to the document object itself. Example: <strong>DOMContentLoaded</strong> (when the HTML is fully loaded and the DOM is ready)</p>
</li>
<li><p><strong>CSS Events</strong>: These events are related to CSS animations. Example: <strong>transitionend</strong> (When a CSS animation finishes)</p>
</li>
</ol>
<p>Now, let's see an example demonstrating the practical application of event handling and input validation in web development:</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">html</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">head</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">title</span>&gt;</span>Input Validation Example<span class="hljs-tag">&lt;/<span class="hljs-name">title</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">script</span>&gt;</span><span class="javascript">
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">checkPhoneNumber</span>(<span class="hljs-params">event</span>) </span>{
  <span class="hljs-keyword">const</span> validKeys = [<span class="hljs-string">'0'</span>, <span class="hljs-string">'1'</span>, <span class="hljs-string">'2'</span>, <span class="hljs-string">'3'</span>, <span class="hljs-string">'4'</span>, <span class="hljs-string">'5'</span>, <span class="hljs-string">'6'</span>, <span class="hljs-string">'7'</span>, <span class="hljs-string">'8'</span>, <span class="hljs-string">'9'</span>, <span class="hljs-string">'+'</span>, <span class="hljs-string">'('</span>, <span class="hljs-string">')'</span>, <span class="hljs-string">'-'</span>];
  <span class="hljs-keyword">if</span> (!validKeys.includes(event.key)) {
    event.preventDefault(); <span class="hljs-comment">// Prevent default action for invalid keys</span>
  }
}
</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">head</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">body</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">label</span> <span class="hljs-attr">for</span>=<span class="hljs-string">"phone"</span>&gt;</span>Enter Phone Number:<span class="hljs-tag">&lt;/<span class="hljs-name">label</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"tel"</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"phone"</span> <span class="hljs-attr">onkeydown</span>=<span class="hljs-string">"checkPhoneNumber(event)"</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>Only digits, +, (, ), and - are allowed.<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">body</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">html</span>&gt;</span>
</code></pre>
<p>In this example, we're implementing input validation for a phone number input field. The <code>onkeydown</code> event triggers the <code>checkPhoneNumber</code> function, which checks if the pressed key is valid (digits, plus sign, parentheses, or hyphen). If the key is not valid, the default action (character input) is prevented.</p>
<p>You can <a target="_blank" href="https://www.freecodecamp.org/news/dom-events-and-javascript-event-listeners/">explore more about events here</a>.</p>
<h3 id="heading-event-handlers">Event Handlers</h3>
<p>To react to these events, we use event handlers. An event handler is simply a function that runs when a specific event occurs. There are different ways to assign event handlers in JavaScript:</p>
<ol>
<li><strong>HTML Attribute</strong>: You can set an event handler directly in the HTML code using an attribute like <code>onclick</code>, <code>onmouseover</code>, etc.</li>
</ol>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">onclick</span>=<span class="hljs-string">"alert('Button clicked!')"</span>&gt;</span>Click me<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
</code></pre>
<ol start="2">
<li><strong>DOM Property</strong>: You can assign a handler using a DOM property like <code>onclick</code>, <code>onmouseover</code>, and so on.</li>
</ol>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"myButton"</span>&gt;</span>Click me<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">script</span>&gt;</span><span class="javascript">
  <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">"myButton"</span>).onclick = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) </span>{
    alert(<span class="hljs-string">'Button clicked!'</span>);
  };
</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>
</code></pre>
<ol start="3">
<li><strong>Event Listeners</strong>: Event listeners are functions that wait for a specific event to occur and then execute a designated function. This is typically done using the <code>addEventListener</code> method. </li>
</ol>
<h3 id="heading-addeventlistener-and-removeeventlistener"><code>addEventListener()</code> and <code>removeEventListener()</code>:</h3>
<p>These are methods used to assign and remove event handlers, respectively, in JavaScript.</p>
<ul>
<li><code>**addEventListener()**</code> is used to attach an event listener to an element, which listens for a specific event (for example, a click or mouseover). It provides more flexibility, especially when you need to add multiple handlers to the same event.</li>
</ul>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"myButton"</span>&gt;</span>Click me<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">script</span>&gt;</span><span class="javascript">
  <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">"myButton"</span>).addEventListener(<span class="hljs-string">'click'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) </span>{
    alert(<span class="hljs-string">'Button clicked!'</span>);
  });
</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>
</code></pre>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> btn = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">'btn'</span>);

<span class="hljs-comment">// Example 1: Adding event listeners directly with anonymous functions</span>
btn.addEventListener(<span class="hljs-string">'click'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">e</span>) </span>{
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"Button clicked!"</span>); <span class="hljs-comment">// Logs a message when the button is clicked</span>
});

<span class="hljs-comment">// Example 2: Defining functions separately and then adding event listeners</span>
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">greet</span>(<span class="hljs-params"></span>) </span>{
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"Hello!"</span>);
}
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">farewell</span>(<span class="hljs-params"></span>) </span>{
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"Goodbye!"</span>);
}
btn.addEventListener(<span class="hljs-string">'mouseenter'</span>, greet); <span class="hljs-comment">// Greets when the mouse enters the button</span>
btn.addEventListener(<span class="hljs-string">'mouseleave'</span>, farewell); <span class="hljs-comment">// Says goodbye when the mouse leaves the button</span>
</code></pre>
<p>With <code>addEventListener</code>, you can also specify additional options as a third argument. Some common options are:</p>
<ul>
<li><code>once</code>: A boolean value that specifies whether the event listener should be removed after it is invoked once.</li>
<li><code>capture</code>: A boolean value that specifies whether the event should be captured during the capturing phase. The capturing phase happens before the bubbling phase.</li>
</ul>
<p>For example:</p>
<pre><code class="lang-javascript">btn.addEventListener(<span class="hljs-string">'click'</span>, handleClick, { <span class="hljs-attr">once</span>: <span class="hljs-literal">true</span>, <span class="hljs-attr">capture</span>: <span class="hljs-literal">true</span> });
</code></pre>
<p>This will add a click event listener to the button element that is triggered only once and captures the event during the capturing phase.</p>
<ul>
<li><code>**removeEventListener()**</code> is used to remove a previously attached event listener from an element. </li>
</ul>
<pre><code class="lang-html">// Example 1

<span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"myButton"</span>&gt;</span>Click me<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">script</span>&gt;</span><span class="javascript">
  <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">handleClick</span>(<span class="hljs-params"></span>) </span>{
    alert(<span class="hljs-string">'Button clicked!'</span>);
  }

  <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">"myButton"</span>).addEventListener(<span class="hljs-string">'click'</span>, handleClick);
  <span class="hljs-comment">// Remove the event handler</span>
  <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">"myButton"</span>).removeEventListener(<span class="hljs-string">'click'</span>, handleClick);
</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>
</code></pre>
<pre><code class="lang-javascript"><span class="hljs-comment">// Example 2</span>
<span class="hljs-comment">// Assume a user preference</span>
<span class="hljs-keyword">const</span> allowGreetings = <span class="hljs-literal">true</span>;

<span class="hljs-comment">// Removing event listeners based on user preference</span>
<span class="hljs-keyword">if</span> (!allowGreetings) {
    btn.removeEventListener(<span class="hljs-string">'mouseenter'</span>, greet);
}
</code></pre>
<h3 id="heading-object-handlers-handleevent">Object Handlers: <code>handleEvent</code></h3>
<p>Instead of assigning a function as an event handler, you can also assign an object that has a <code>handleEvent</code> method. When the event occurs, the <code>handleEvent</code> method of the object will be called.</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"myButton"</span>&gt;</span>Click me<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">script</span>&gt;</span><span class="javascript">
  <span class="hljs-keyword">let</span> myObject = {
    <span class="hljs-attr">handleEvent</span>: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">event</span>) </span>{
      alert(<span class="hljs-string">'Button clicked!'</span>);
    }
  };

  <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">"myButton"</span>).addEventListener(<span class="hljs-string">'click'</span>, myObject);
</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>
</code></pre>
<p>In this example, when the button is clicked, the <code>handleEvent</code> method of <code>myObject</code> is called.</p>
<h3 id="heading-event-object">Event Object:</h3>
<p>When an event occurs, the browser creates an event object that contains information about the event, such as the type of event, the target element, and any additional data. </p>
<p>This object is passed as an argument to the event handler function which can be accessed within the callback function of an event listener.</p>
<pre><code class="lang-javascript">element.addEventListener(<span class="hljs-string">'click'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">event</span>) </span>{
    <span class="hljs-built_in">console</span>.log(event.type); <span class="hljs-comment">// Output: "click"</span>
    <span class="hljs-built_in">console</span>.log(event.target); <span class="hljs-comment">// Output: The element that was clicked</span>
     <span class="hljs-comment">// We can access more properties like event.clientX, event.clientY, etc.</span>
});
</code></pre>
<h3 id="heading-event-propagation">Event Propagation:</h3>
<p>Events in the DOM can propagate through the DOM tree in two phases: the capturing phase and bubbling phase. </p>
<p>When an event happens on an element, like a click or a key press, the browser needs to decide which elements should be notified about the event. </p>
<p>Event capturing and bubbling describe the order in which elements are notified about the event. Understanding event propagation is important when dealing with nested elements and event delegation.</p>
<ol>
<li><strong>Capturing Phase</strong>: In the capturing phase, the event starts from the top of the DOM hierarchy (usually the <code>&lt;html&gt;</code> element) and travels down to the target element. During this phase, event handlers attached with <code>addEventListener</code> and the <code>capture</code> option set to <code>true</code> are triggered. These handlers are executed before the event reaches the target element.</li>
<li><strong>Target Phase</strong>: Once the event reaches the target element, it enters the target phase. Event handlers attached with <code>addEventListener</code> without the <code>capture</code> option (or with <code>false</code> as the value) are triggered during this phase. Handlers attached in this phase are executed when the event is directly targeting the element.</li>
<li><strong>Bubbling Phase</strong>: After the target phase, the event bubbles up from the target element to the top of the DOM hierarchy. During this phase, event handlers attached with <code>addEventListener</code> without the <code>capture</code> option (or with <code>false</code> as the value) are triggered again. Handlers attached in this phase are executed as the event travels up from the target element.</li>
</ol>
<p>Let's look at an example. Consider a <code>&lt;div&gt;</code> nested inside another <code>&lt;div&gt;</code>. If a click event occurs on the inner <code>&lt;div&gt;</code>, the capturing phase starts from the outer <code>&lt;div&gt;</code> and goes down to the inner <code>&lt;div&gt;</code>. Then, the target phase happens on the inner <code>&lt;div&gt;</code>, and finally, the bubbling phase occurs from the inner <code>&lt;div&gt;</code> back up to the outer <code>&lt;div&gt;</code>.</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"outerDiv"</span>&gt;</span>
  Outer Div
  <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"innerDiv"</span>&gt;</span>Inner Div<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>

<span class="hljs-tag">&lt;<span class="hljs-name">script</span>&gt;</span><span class="javascript">
  <span class="hljs-keyword">const</span> outerDiv = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">'outerDiv'</span>);
  <span class="hljs-keyword">const</span> innerDiv = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">'innerDiv'</span>);

  outerDiv.addEventListener(<span class="hljs-string">'click'</span>, <span class="hljs-function">() =&gt;</span> <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'Capturing: Outer Div'</span>), <span class="hljs-literal">true</span>);
  innerDiv.addEventListener(<span class="hljs-string">'click'</span>, <span class="hljs-function">() =&gt;</span> <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'Target: Inner Div'</span>));
  outerDiv.addEventListener(<span class="hljs-string">'click'</span>, <span class="hljs-function">() =&gt;</span> <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'Bubbling: Outer Div'</span>));
</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>
</code></pre>
<p>Let's understand Bubbling in detail.</p>
<h3 id="heading-event-bubbling">Event Bubbling:</h3>
<p>Event bubbling is a mechanism in JavaScript where, when an event occurs on an element, such as a click, that event first triggers on the target element and then "bubbles" up through its ancestor elements all the way up to the root of the document (usually <code>&lt;html&gt;</code>). This triggers the same event on each ancestor along the way. Here's an example:</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">form</span> <span class="hljs-attr">onclick</span>=<span class="hljs-string">"alert('form')"</span>&gt;</span>
  FORM
  <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">onclick</span>=<span class="hljs-string">"alert('div')"</span>&gt;</span>
    DIV
    <span class="hljs-tag">&lt;<span class="hljs-name">p</span> <span class="hljs-attr">onclick</span>=<span class="hljs-string">"alert('p')"</span>&gt;</span>P<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">form</span>&gt;</span>
</code></pre>
<p>If you click on the <code>&lt;p&gt;</code> element, the click event will first trigger on the <code>&lt;p&gt;</code> element, then on the <code>&lt;div&gt;</code>, and finally on the <code>&lt;form&gt;</code>. This is because the event bubbles up through each parent element in the DOM hierarchy.</p>
<p><strong><code>event.target</code></strong> vs. <code>this</code>:</p>
<ul>
<li><code>event.target</code> refers to the element that initiated the event. It remains the same throughout the bubbling process. In the above example, if you click on the <code>&lt;p&gt;</code> element, <code>event.target</code> will be the <code>&lt;p&gt;</code> element.</li>
<li><code>this</code> (or <code>event.currentTarget</code>) refers to the current element that the event handler is attached to. In the above example, if the event handler is attached to the <code>&lt;form&gt;</code>, <code>this</code> will be the <code>&lt;form&gt;</code> element.</li>
</ul>
<h4 id="heading-how-to-stop-event-bubbling">How to stop event bubbling:</h4>
<p>Sometimes, you might want to stop the event from bubbling up further. You can do this using the <code>event.stopPropagation()</code> method. This method stops the event from propagating to parent elements.</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">body</span> <span class="hljs-attr">onclick</span>=<span class="hljs-string">"alert('the bubbling doesn't reach here')"</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">onclick</span>=<span class="hljs-string">"event.stopPropagation()"</span>&gt;</span>Click here<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">body</span>&gt;</span>
</code></pre>
<p>In this example, clicking the button won't trigger the <code>alert</code> on the body element because <code>event.stopPropagation()</code> is called in the button's click event handler.</p>
<p><code>event.stopImmediatePropagation()</code> is similar to <code>event.stopPropagation()</code>, but also prevents other handlers on the current element from executing.</p>
<h3 id="heading-event-delegation">Event Delegation:</h3>
<p>Event delegation is a technique that allows you to handle events more efficiently by attaching a single event listener to a parent element instead of attaching multiple event listeners to individual child elements. This is particularly useful when you have a large number of similar elements that need the same event handling logic.</p>
<pre><code class="lang-javascript">parentElement.addEventListener(<span class="hljs-string">'click'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">event</span>) </span>{
    <span class="hljs-keyword">if</span> (event.target.classList.contains(<span class="hljs-string">'childElement'</span>)) {
        <span class="hljs-comment">// Action to be performed when a child element is clicked</span>
    }
});
</code></pre>
<pre><code class="lang-javascript">&lt;!-- Example: Event delegation --&gt;
<span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">ul</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"myList"</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">li</span>&gt;</span>Item 1<span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">li</span>&gt;</span>Item 2<span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">li</span>&gt;</span>Item 3<span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">ul</span>&gt;</span></span>

<span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">script</span>&gt;</span><span class="javascript">
    <span class="hljs-comment">// Adding a click event listener to the parent ul element</span>
    <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">"myList"</span>).addEventListener(<span class="hljs-string">"click"</span>, <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">event</span>) </span>{
        <span class="hljs-comment">// Checking if the clicked element is an li</span>
        <span class="hljs-keyword">if</span> (event.target.tagName === <span class="hljs-string">"LI"</span>) {
            <span class="hljs-comment">// Code to execute when an li is clicked</span>
            <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"Item clicked:"</span>, event.target.textContent);
        }
    });
</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span></span>
</code></pre>
<p>This approach reduces the number of event listeners and improves performance.</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>The DOM, or Document Object Model, is an interface that represents the structure of HTML documents. It serves as the bridge between JavaScript code and the browser, allowing manipulation of HTML elements, styles, attributes, and event handling. </p>
<p>The DOM API provides methods and properties to interact with the DOM tree. Examples include <code>querySelector</code>, <code>addEventListener</code>, <code>createElement</code>, <code>innerHTML</code>, <code>textContent</code>, etc.</p>
<p>Through DOM manipulation, developers can dynamically change various aspects of a web page, including text content, HTML attributes, and the structure of the document itself (for example, inserting, updating, or deleting HTML elements).</p>
<p>JavaScript frameworks and libraries like React often utilize DOM manipulation capabilities to efficiently manage and update user interfaces. This lets developers create complex web applications with interactive and responsive user experiences.</p>
<p>To learn more about the DOM, here are a few resources you can check out:</p>
<p>First of all, I wrote a follow-up article, which you can find here:<br><a class="post-section-overview" href="#https://www.freecodecamp.org/news/form-validation-in-javascript/">Client-Side Form Handling with JavaScript</a>.</p>
<p>You can also read more in the following articles:</p>
<ul>
<li><a target="_blank" href="https://www.samyakinfo.tech/blog/document-and-resource-loading">DOM Events Lifecycle and Efficient script Loading</a></li>
<li>The <a target="_blank" href="https://www.freecodecamp.org/news/the-javascript-dom-manipulation-handbook/">JavaScript DOM manipulation handbook</a></li>
<li>The <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/API/Document_Object_Model">MDN</a> web docs</li>
<li><a target="_blank" href="https://www.freecodecamp.org/news/dom-manipulation-best-practices/">JavaScript DOM manipulation best practices</a></li>
<li><a target="_blank" href="https://www.freecodecamp.org/news/learn-javascript-for-dom-manipulation-in-spanish-course-for-beginners/">JS DOM manipulation in Spanish - full course</a></li>
</ul>
<p></p> ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Use the JavaScript insertAdjacentHTML() method for Efficient DOM Manipulation ]]>
                </title>
                <description>
                    <![CDATA[ In JavaScript, developers need to be able to dynamically update a page without replacing the entire content. A traditional method like innerHTML can cause performance issues, because these methods tend to replace the entire content of an element. The... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/javascript-insertadjacenthtml-method-efficient-dom-manipulation/</link>
                <guid isPermaLink="false">66d03966871ae63f179f6be9</guid>
                
                    <category>
                        <![CDATA[ DOM ]]>
                    </category>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Kamaldeen Lawal ]]>
                </dc:creator>
                <pubDate>Wed, 07 Feb 2024 16:28:17 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2024/02/The-JavaScript-insertAdjacentHTML---Method.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>In JavaScript, developers need to be able to dynamically update a page without replacing the entire content. A traditional method like <code>innerHTML</code> can cause performance issues, because these methods tend to replace the entire content of an element.</p>
<p>The <code>insertAdjacentHTML()</code> method leads to better performance because you use it to dynamically insert new HTML content without affecting the existing content.</p>
<p>In this tutorial, we'll cover the following:</p>
<ul>
<li><a class="post-section-overview" href="#heading-introduction-to-the-insertadjacenthtml-method">Introduction to the <code>insertAdjacentHTML()</code> method</a></li>
<li><a class="post-section-overview" href="#heading-syntax-of-the-insertadjacenthtml-method">Syntax of the <code>insertAdjacentHTML()</code> method</a></li>
<li><a class="post-section-overview" href="#placement-options-in-insertadjacenthtml-method">Placement options in the</a> <a class="post-section-overview" href="#placement-options-in-insertadjacenthtml-method"><code>insertAdjacentHTML()</code> method</a></li>
<li><a class="post-section-overview" href="#browser-support-for-the-inneradjacenthtml-method">Browser support for the <code>insertAdjacentHTML()</code> method</a></li>
<li><a class="post-section-overview" href="#best-practices-for-using-theinsertadjacenthtml-method">Best Practices for using the</a> <a class="post-section-overview" href="#best-practices-for-using-theinsertadjacenthtml-method"><code>insertAdjacentHTML()</code> method</a></li>
<li><a class="post-section-overview" href="#heading-conclusion">Conclusion</a></li>
</ul>
<h2 id="heading-introduction-to-the-insertadjacenthtml-method">Introduction to the <code>insertAdjacentHTML()</code> method</h2>
<p>The <code>insertAdjacentHTML()</code> method provides an efficient way to manipulate web page structure without replacing all the content of an element. It's also the go-to method for inserting HTML elements or text elements into a specific position.</p>
<p><code>insertAdjacentHTML</code> is a method in JavaScript that allows you to insert HTML elements or text into a specific position relative to a given element in the DOM (Document Object Model). This method provides flexibility in manipulating the structure of a web page dynamically.</p>
<h2 id="heading-syntax-of-the-insertadjacenthtml-method">Syntax of the <code>insertAdjacentHTML()</code> method</h2>
<p>Here's what the syntax of the <code>insertAdjacentHTML()</code> method looks like:</p>
<pre><code class="lang-javascript">HTMLelement.insertAdjacentHTML(position, element);
</code></pre>
<p>The <code>insertAdjacentHTML</code> method takes two parameters:</p>
<ol>
<li><p><strong>position:</strong> This parameter is a string representation of where the new HTML should be inserted in relation to the <code>targetElement</code>. It must match one of the following strings:</p>
</li>
<li><p><code>**"beforebegin"**</code>: The <code>beforebegin</code> string value of the <code>insertAdjacentHTML()</code> method inserts the HTML element immediately before the specified element in the <code>DOM</code>.</p>
</li>
<li><code>**"afterbegin"**</code>: The <code>afterbegin</code> string value of the<code>insertAdjacentHTML()</code> method inserts the HTML element inside the <code>targetElement</code>, just before its first child.</li>
<li><code>**"beforeend"**</code>: The <code>beforeend</code> is a string value of  the <code>insertAdjacentHTML()</code> method that  inserts an HTML element inside the <code>targetElement</code>, after its last child.</li>
<li><p><code>**"afterend"**</code>: The <code>afterend</code> string value of the <code>insertAdjacentHTML()</code> method inserts an HTML element immediately after the specified element in the <code>DOM</code>.</p>
</li>
<li><p><strong>element:</strong> The element to be inserted into the <code>DOM</code> tree.</p>
</li>
</ol>
<h2 id="heading-placement-options-in-the-insertadjacenthtml-method">Placement Options in the <code>insertAdjacentHTML()</code> Method</h2>
<p>Now that you've seen the four possible parameters of the <code>insertAdjacentHTML()</code> method, let's see how they work with code.</p>
<ul>
<li><code>beforebegin</code>: Here's an example using the <code>beforebegin</code> parameter in code:</li>
</ul>
<pre><code class="lang-javascript">
<span class="hljs-keyword">const</span> targetElement = <span class="hljs-built_in">document</span>.querySelector(<span class="hljs-string">'h1'</span>);
targetElement.insertAdjacentHTML(<span class="hljs-string">'beforebegin'</span>, <span class="hljs-string">'&lt;h2&gt;Lawal&lt;/h2&gt;'</span>);
</code></pre>
<p>Here's the output:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/02/beforebegin.png" alt="beforebegin" width="600" height="400" loading="lazy">
<em>beforebegin</em></p>
<p>Recall that the <code>beforebegin</code> string value of the <code>insertAdjacentHTML()</code> method inserts the HTML element immediately before the specified element in the <code>DOM</code>.</p>
<p>In the above code result, our newly inserted HTML element <code>h3</code> got inserted before our <code>targetElement</code> <code>h2</code>. I styleed our <code>targetElement</code> by adding a border to it for easy illustration.</p>
<ul>
<li><code>afterbegin</code>: here's an example of using the <code>afterbegin</code> parameter in code:</li>
</ul>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> targetElement = <span class="hljs-built_in">document</span>.querySelector(<span class="hljs-string">'h1'</span>);
targetElement.insertAdjacentHTML(<span class="hljs-string">'afterbegin'</span>, <span class="hljs-string">'&lt;h2&gt;Lawal&lt;/h2&gt;'</span>);
</code></pre>
<p>And here's the output:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/02/afterbegin.png" alt="afterbegin" width="600" height="400" loading="lazy">
<em>afterbegin</em></p>
<p>As defined above, the <code>afterbegin</code> string value of the <code>insertAdjacentHTML()</code> method inserts the HTML element inside the <code>targetElement</code>, just before its first child.</p>
<p>By checking the output of our code, you may realize that our newly inserted HTML element <code>h3</code> got inserted inside our <code>targetElement</code> <code>h2</code>. Again, I styled our <code>targetElement</code> by adding a border to it for easy illustration.</p>
<ul>
<li><code>beforeend</code>: here's an example of using <code>beforeend</code> in code:</li>
</ul>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> targetElement = <span class="hljs-built_in">document</span>.querySelector(<span class="hljs-string">'h1'</span>);
targetElement.insertAdjacentHTML(<span class="hljs-string">'beforeend'</span>, <span class="hljs-string">'&lt;h2&gt;Lawal&lt;/h2&gt;'</span>);
</code></pre>
<p>And here's the output:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/02/beforeend.png" alt="beforeend" width="600" height="400" loading="lazy">
<em>beforeend</em></p>
<p>The general definition of <code>beforeend</code> is that it's a string value of the <code>insertAdjacentHTML()</code> method that inserts an HTML element inside the <code>targetElement</code>, after its last child.</p>
<p>From the code result, our newly inserted <code>HTML</code> element <code>h3</code> got inserted inside our <code>targetElement</code> <code>h2</code> after its child. I styled our <code>targetElement</code> by adding a border to it for easy illustration.</p>
<ul>
<li><code>afterend</code>: here's an example of using <code>aferend</code> in code:</li>
</ul>
<pre><code class="lang-javscript">const targetElement = document.querySelector('h1');
targetElement.insertAdjacentHTML('afterend', '&lt;h2&gt;Lawal&lt;/h2&gt;');
</code></pre>
<p>And here's the output:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/02/afterend.png" alt="afterend" width="600" height="400" loading="lazy">
<em>afterend</em></p>
<p>As you now know, <code>afterend</code>  is a string value of the <code>insertAdjacentHTML()</code> method that inserts an <code>HTML</code> element immediately after the specified element in the <code>DOM</code>.</p>
<p>In the above code, our newly inserted HTML element <code>h3</code> got inserted immediately after our <code>targetElement</code> <code>h2</code>. I styled our <code>targetElement</code> by adding a border to it for easy illustration.</p>
<h2 id="heading-browser-support-for-the-insertadjacenthtml-method">Browser Support for the <code>insertAdjacentHTML()</code> Method</h2>
<p>The <code>insertAdjacentHTML()</code> method is a widely supported method that can be relied upon for your <code>DOM</code> manipulation needs across different modern browsers. </p>
<p>To see the browsers that support this method, check out the summary below:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/02/browser-compat.png" alt="browser compatibility" width="600" height="400" loading="lazy">
<em>browser compatibility</em></p>
<ol>
<li><strong>Edge</strong>: Supported across all versions.</li>
<li><strong>Chrome</strong>: Supported across all versions.</li>
<li><strong>Opera</strong>: Supported across all versions.</li>
<li><strong>Safari</strong>: Supported across all versions, except version 3.1-3.2</li>
<li><strong>Firefox</strong>: Supported across all versions, except version 2-7</li>
</ol>
<h2 id="heading-best-practices-for-using-the-insertadjacenthtml-method">Best Practices for Using the <code>insertAdjacentHTML()</code> Method</h2>
<p>To effectively use the <code>insertAdjacentHTML()</code> method, here are some best practices to follow:</p>
<h3 id="heading-understand-the-method">Understand the method</h3>
<p>Understanding how the method works helps you specify the position to insert your HTML content. Understand the various positions and choose appropriately based on your requirements.</p>
<pre><code class="lang-javascript"><span class="hljs-comment">// Inserting the HTML content after the target element</span>
<span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">'div'</span>).insertAdjacentHTML(<span class="hljs-string">'afterend'</span>, <span class="hljs-string">'&lt;div&gt;New content before the target element&lt;/div&gt;'</span>);
</code></pre>
<h3 id="heading-use-it-sparingly">Use it sparingly</h3>
<p>Overusing dynamic HTML element insertion methods is bad for code maintenance.</p>
<p>For a simple application, a direct <code>DOM</code> manipulation will do the job.</p>
<pre><code class="lang-javascript">/ Consider Using <span class="hljs-built_in">this</span>:
<span class="hljs-keyword">let</span> newElement = <span class="hljs-built_in">document</span>.createElement(<span class="hljs-string">'div'</span>);
newElement.textContent = <span class="hljs-string">'New element'</span>;
element.appendChild(newElement);


<span class="hljs-comment">// Instead of this:</span>
element.insertAdjacentHTML(<span class="hljs-string">'beforeend'</span>, <span class="hljs-string">'&lt;div&gt;New element&lt;/div&gt;'</span>);
</code></pre>
<h3 id="heading-be-conscious-of-performance">Be conscious of performance</h3>
<p>If you frequently insert large amounts of HTML content, manipulating the <code>DOM</code> can be expensive for performance. Try to minimize <code>DOM</code> updates, especially in performance scenarios:</p>
<pre><code class="lang-javascript">

<span class="hljs-comment">// Consider using batch insertion:</span>
<span class="hljs-keyword">let</span> section = <span class="hljs-string">''</span>;
data.forEach(<span class="hljs-function"><span class="hljs-params">item</span> =&gt;</span> {
  section += <span class="hljs-string">`&lt;div&gt;<span class="hljs-subst">${item}</span>&lt;/div&gt;`</span>;
});
element.insertAdjacentHTML(<span class="hljs-string">'beforeend'</span>, section);


<span class="hljs-comment">// Instead of inserting one by one in a loop:</span>
data.forEach(<span class="hljs-function"><span class="hljs-params">item</span> =&gt;</span> {
  element.insertAdjacentHTML(<span class="hljs-string">'beforeend'</span>, <span class="hljs-string">`&lt;div&gt;<span class="hljs-subst">${item}</span>&lt;/div&gt;`</span>);
});
</code></pre>
<h3 id="heading-handling-errors">Handling errors</h3>
<p>When using the <code>insertAdjacentHTML()</code> method, if the HTML content you're trying to insert is invalid, the method may throw an error. Use try-catch blocks to handle these situations appropriately. </p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> div  = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">'div'</span>);

<span class="hljs-keyword">try</span> {
    <span class="hljs-comment">// Check if the value of div is true</span>
    <span class="hljs-keyword">if</span> (div.insertAdjacentHTML) {
        div.insertAdjacentHTML(<span class="hljs-string">'beforeend'</span>, <span class="hljs-string">'&lt;div&gt;New Element&lt;/div&gt;'</span>);
    } <span class="hljs-keyword">else</span> {
        <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Error</span>(<span class="hljs-string">'insertAdjacentHTML is not supported.'</span>);
    }
} <span class="hljs-keyword">catch</span> (error) {
    <span class="hljs-comment">// Handling the error</span>

    <span class="hljs-built_in">console</span>.error(<span class="hljs-string">'Error:'</span>, error.message);


    <span class="hljs-comment">// Alternate code</span>
    div.innerHTML += <span class="hljs-string">'&lt;div&gt;Fallback: New Element&lt;/div&gt;'</span>;
}
</code></pre>
<h2 id="heading-conclusion">Conclusion</h2>
<p>In this tutorial, you learned about the syntax and placement options of the <code>insertAdjacentHTML()</code> method. We also looked at browser compatibility, and some best practices while using the <code>insertAdjacentHTML()</code> method.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ JS DOM Manipulation Best Practices – with Examples ]]>
                </title>
                <description>
                    <![CDATA[ In JavaScript, you can manipulate the content of a web page using the Document Object Model (DOM). But how do you write code that is readable, easy to maintain, and not prone to performance issues? That's what we'll cover in this article. I'll discus... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/dom-manipulation-best-practices/</link>
                <guid isPermaLink="false">66d45dd6aad1510d0766b5e9</guid>
                
                    <category>
                        <![CDATA[ best practices ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Document Object Model ]]>
                    </category>
                
                    <category>
                        <![CDATA[ DOM ]]>
                    </category>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Benjamin Semah ]]>
                </dc:creator>
                <pubDate>Fri, 12 Jan 2024 17:41:27 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2024/01/freecodecamp-javascript-benjamin-semah.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>In JavaScript, you can manipulate the content of a web page using the Document Object Model (DOM). But how do you write code that is readable, easy to maintain, and not prone to performance issues?</p>
<p>That's what we'll cover in this article. I'll discuss some important best practices so that you can manipulate the DOM with confidence.</p>
<h2 id="heading-table-of-contents">Table of Contents</h2>
<ul>
<li><p><a class="post-section-overview" href="#">Introduction</a></p>
</li>
<li><p><a class="post-section-overview" href="#user-the-domcontentloaded-event">Use the DOMContentLoaded Event</a></p>
</li>
<li><p><a class="post-section-overview" href="#cache-selected-elements">Cache Selected Elements</a></p>
</li>
<li><p><a class="post-section-overview" href="#query-parent-elements-instead-of-document">Query Parent Instead of Document</a></p>
</li>
<li><p><a class="post-section-overview" href="#use-css-classes-to-style-elements">Use CSS Classes to Style Elements</a></p>
</li>
<li><p><a class="post-section-overview" href="#use-innerhtml-with-caution">Use innerHTML With Caution</a></p>
</li>
<li><p><a class="post-section-overview" href="#write-readable-event-listeners">Write Readable Event Listeners</a></p>
</li>
<li><p><a class="post-section-overview" href="#use-event-delegation-to-handle-dom-events">Use Event Delegation to Handle DOM Events</a></p>
</li>
<li><p><a class="post-section-overview" href="#batch-dom-updates-with-fragment">Batch DOM Updates With Fragment</a></p>
</li>
<li><p><a class="post-section-overview" href="#use-the-stoppropagation-method">Use the stopPropagation Method</a></p>
</li>
<li><p><a class="post-section-overview" href="#test-your-dom-manipulation-code">Test your DOM Manipulation code</a></p>
</li>
<li><p><a class="post-section-overview" href="#conclusion">Conclusion</a></p>
</li>
</ul>
<h2 id="heading-user-the-domcontentloaded-event">User the <code>DOMContentLoaded</code> Event</h2>
<p>The <code>DOMContentLoaded</code> event is fired when the HTML document is fully loaded. Using this event ensures that your DOM manipulation code runs only after the document is fully loaded.</p>
<p>To use the <code>DOMContentLoaded</code>, add an event listener to the document and listen for the <code>DOMContentLoaded</code> event. This helps prevent any issues that may come up when you try to manipulate elements that are yet to be rendered.</p>
<p>Example:</p>
<pre><code class="lang-javascript"><span class="hljs-built_in">document</span>.addEventListener(<span class="hljs-string">'DOMContentLoaded'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-comment">// Your DOM manipulation code goes here...</span>
})
</code></pre>
<h2 id="heading-cache-selected-elements">Cache Selected Elements</h2>
<p>When you have frequently used elements, querying the DOM for the same element anytime over and over is inefficient. It's better to query the DOM once and store the result in variables.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> cachedElement = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">'exampleId'</span>)
</code></pre>
<p>This way you can reference the variables anytime you want to use them. This helps improve performance as it reduces unnecessary work.</p>
<h2 id="heading-query-parent-elements-instead-of-document">Query Parent Elements Instead of Document</h2>
<p>When you cache an element, you can also query it to select any of its descendants. This can help improve performance because it limits the scope of the query and reduces the number of times the entire document is queried.</p>
<p>Example:</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"parent"</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">p</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"child"</span>&gt;</span>Example paragraph<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
</code></pre>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> parentElement = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">'parent'</span>)

<span class="hljs-comment">// Options 1: Querying entire document ❌</span>
<span class="hljs-keyword">const</span> childFromDocument = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">'child'</span>) 

<span class="hljs-comment">// Options 2: Query the parent element ✅</span>
<span class="hljs-keyword">const</span> childFromParent = parentElement.querySelector(<span class="hljs-string">'#child'</span>)
</code></pre>
<p>In the example above is a simple markup containing a <code>#parent</code> div and <code>.child</code> paragraph. Then there are two options for selecting the child element.</p>
<p>Technically, both options are correct and will select the same element. But the difference is in the scope of the query.</p>
<p>Example 1 queries (or searches) the entire document to find and select the child. This is less performant and not even necessary because the parent of the element you intend to select is already cached.</p>
<p>Example 2 narrows the scope of the query (or search) by querying only the parent element and not the whole document. That's why it's preferred because it's more performant – especially when the document is large.</p>
<p>Also, note that the method used for querying the parent is <code>querySelector</code>. Using <code>getElementById</code> to query the parent won't work and will result in an error.</p>
<h2 id="heading-use-css-classes-to-style-elements">Use CSS Classes to Style Elements</h2>
<p>It's best to use CSS classes to style elements instead of using inline styles. Classes are easy to maintain compared to inline styles which can be hard to manage.</p>
<p>The <code>classList</code> property has useful properties like add, remove, toggle, and others that makes it easy to modify styles.</p>
<p>Example:</p>
<pre><code class="lang-css"><span class="hljs-selector-class">.styledClass</span> {
  <span class="hljs-attribute">color</span>: red;
}
</code></pre>
<pre><code class="lang-javascript">element.classList.add(<span class="hljs-string">'styledClass'</span>)
</code></pre>
<p>This example uses the <code>.add</code> property of <code>classList</code> to add the <code>styledClass</code> to the element. Assuming you wanted to remove the class from the element, you can easily do so using the <code>.remove</code> property in place of add.</p>
<h2 id="heading-use-innerhtml-with-caution">Use <code>innerHTML</code> with Caution</h2>
<p>The <code>innerHTML</code> property reads and parses HTML markup that you pass to it. This means it can read and run code in a script tag passed to it. And this can pose a security risk to your application.</p>
<p>Where possible, use the <code>innerText</code> or <code>textContent</code> property to render strings. But if you need to use <code>innerHTML</code>, be sure you're using it to insert content from trusted sources. Or sanitize and validate the provided content with a library like DOMPurify.</p>
<p>You can read <a target="_blank" href="https://www.freecodecamp.org/news/innerhtml-vs-innertext-vs-textcontent/#what-is-the-innerhtml-property">this freeCodeCamp article</a> to learn more about <code>innerHTML</code>.</p>
<h2 id="heading-write-readable-event-listeners">Write Readable Event Listeners</h2>
<p>Often you will pass two arguments to event listeners. The first is the event you're listening to and the second is the event handler (the function that fires when the event occurs).</p>
<p>To make your code easy to read and maintain, you can define the event handler function outside of the event listener. Then you can call it within the even listener, like in example 1 below:</p>
<pre><code class="lang-javascript">Example <span class="hljs-number">1</span> ✅

MyElement.addEventListener(<span class="hljs-string">'click'</span>, handleClick) 

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">handleClick</span>(<span class="hljs-params"></span>) </span>{ 
    <span class="hljs-comment">// your logic goes here.. </span>
} 

<span class="hljs-comment">// Example 2 ❌ </span>

myElement.addEventListener(<span class="hljs-string">'click'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) </span>{ 
    <span class="hljs-comment">// your logic goes here... </span>
})
</code></pre>
<p>Both are technically correct and will do the same thing. But example 1 is preferred because it's easier to read. Also, you can reuse the <code>handleClick</code> function if you need to. This helps you observe the DRY (Don't Repeat Yourself) principle.</p>
<h2 id="heading-use-event-delegation-to-handle-dom-events">Use Event Delegation to Handle DOM Events</h2>
<p>Event delegation is when you attach an event listener on a parent element to listen to events on its descendants. With this technique, you can reduce the number of event listeners to include in your code.</p>
<p>For example, assume you have five buttons inside a parent div:</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"parent"</span>&gt;</span> 
    <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"btn-1"</span>&gt;</span>1st Button<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span> 
    <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"btn-2"</span>&gt;</span>2nd Button<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span> 
    <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"btn-3"</span>&gt;</span>3rd Button<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span> 
    <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"btn-4"</span>&gt;</span>4th Button<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span> 
    <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"btn-5"</span>&gt;</span>5th Button<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span> 
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
</code></pre>
<p>You can add an event listener to each of the five buttons to listen to a click. Or using event delegation, you can a single event on only the parent div:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> parentElement = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">'parent'</span>) 

parentElement.addEventListener(<span class="hljs-string">'click'</span>, handleClick) 

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">handleClick</span>(<span class="hljs-params">event</span>) </span>{ 
  alert(event.target.id) 
}
</code></pre>
<p>In this example, the event to delegated to the parent element. And we're using <code>event.target.id</code> to get the actual button the user clicked. If you are curious, you can <a target="_blank" href="https://stackblitz.com/edit/js-r3qjyd?file=index.html,index.js">run the code on Stackblitz</a> to see how it works.</p>
<p>Event delegation help saves time improve performance. Imagine how this technique can come in handy when dealing with a large amount of dynamic content.</p>
<h2 id="heading-batch-dom-updates-with-fragment">Batch DOM Updates With Fragment</h2>
<p>Frequent updates to the DOM can affect the performance of your application. Try to reduce the number of updates where possible.</p>
<p>A useful feature you can use to batch updates is the <code>.createDocumentFragment</code> property. It allows you to group multiple updates before inserting them into the document. This reduces reflows and makes your code more effecient.</p>
<p>Example without Fragment:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> container = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">'container'</span>)

<span class="hljs-keyword">for</span> (<span class="hljs-keyword">let</span> i = <span class="hljs-number">0</span>; i &lt; <span class="hljs-number">1000</span>; i++) { 
    <span class="hljs-keyword">const</span> listItem = <span class="hljs-built_in">document</span>.createElement(<span class="hljs-string">'li'</span>)
    listItem.textContent = <span class="hljs-string">`Item <span class="hljs-subst">${i}</span>`</span>
    container.appendChild(listItem) 
}
</code></pre>
<p>This code updates with each iteration of the loop. That means the DOM will be update 1,000 times. There is a more efficient way of doing this with the code below that uses fragment.</p>
<p>Example with fragment:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> container = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">'container'</span>) 
<span class="hljs-keyword">const</span> fragment = <span class="hljs-built_in">document</span>.createDocumentFragment()

<span class="hljs-comment">// Add multiple list items to the fragment </span>
<span class="hljs-keyword">for</span> (<span class="hljs-keyword">let</span> i = <span class="hljs-number">0</span>; i &lt; <span class="hljs-number">1000</span>; i++) { 
    <span class="hljs-keyword">const</span> listItem = <span class="hljs-built_in">document</span>.createElement(<span class="hljs-string">'li'</span>) 
    listItem.textContent = <span class="hljs-string">`Item <span class="hljs-subst">${i}</span>`</span> 
    fragment.appendChild(listItem)
} 

container.appendChild(fragment)
</code></pre>
<p>The code above appends the <code>listItem</code> to the <code>fragment</code> with each iteration of the loop. It only appends the child to the <code>container</code> element after the loop is done running. This means the DOM is updated only once instead of 1,000 times like before.</p>
<h2 id="heading-use-the-stoppropagation-method">Use the <code>stopPropagation</code> Method</h2>
<p>The <code>stopPropagation</code> method controls the flow of events in the DOM. By default, when an event occurs on an element, it bubbles (propagates) through its ancestors.</p>
<p>This event propagating behaviour can sometimes lead to unintended results. The <code>stopPropagation</code> method provides a way to stop the event from propagating to the parent and other ancestors.</p>
<p>Let's take a situation where you have a button inside a parent div. And you want to handle a click event on the button without registering the click on the div:</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"container"</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"button"</span>&gt;</span>Click me<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
</code></pre>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> containerDiv = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">'container'</span>)
<span class="hljs-keyword">const</span> buttonElement = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">'button'</span>)

containerDiv.addEventListener(<span class="hljs-string">'click'</span>, handleDivClick)
buttonElement.addEventListener(<span class="hljs-string">'click'</span>, handleBtnClick)

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">handleDivClick</span>(<span class="hljs-params"></span>) </span>{ 
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'Div clicked'</span>)
} 

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">handleBtnClick</span>(<span class="hljs-params">event</span>) </span>{ 
    event.stopPropagation()
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'Button clicked'</span>)
}
</code></pre>
<p>Without using the <code>stopPropagation</code> method, a click event on the button will also trigger a click event on the parent div. This means both event handlers will run.</p>
<p>But the <code>event.stopPropagation()</code> line in the code will prevent the <code>handleDivClick</code> function from running when a user clicks the button.</p>
<p>You can <a target="_blank" href="https://stackblitz.com/edit/js-wjmnd5?file=index.html,index.js">run the code on Stackblitz</a> to see how it works. Comment out the line with the <code>stopPropagation</code> method and see the difference.</p>
<h2 id="heading-test-your-dom-manipulation-code">Test Your DOM Manipulation Code</h2>
<p>When you write tests, you create scenarios that mimic user interactions or application states. You also verify that your application gives you the expected outcomes.</p>
<p>Testing your DOM manipulation code is a best practice because it will make your code reliable and easy to maintain. It also gives you confidence that your code behaves as expected, even as it evolves over time when you make changes and add features.</p>
<p>You can use testing frameworks and libraries available for JavaScript, such as Jest, Mocha, Jasmine, and others to automate testing your apps.</p>
<p>The following example uses the Jest framework to test DOM Manipulation code for adding a class to an element.</p>
<pre><code class="lang-javascript">test(<span class="hljs-string">'Adding a highlight class changes text color to red'</span>, <span class="hljs-function">() =&gt;</span> {
    myElement.classList.add(<span class="hljs-string">'highlight'</span>);
    expect(getComputedStyle(myElement).color).toBe(<span class="hljs-string">'red'</span>);
});
</code></pre>
<p>Adding the <code>highlight</code> class is expected to change the text color to red. If the test passes, it means your DOM manipulation code works as expected. If not, you will need to figure out what figure out what's wrong and fix the issue.</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>In this article you've learned ten best practices to keep in mind when working with the DOM. Some of them are general while others are situation specific. By using these best practices in your workflow, you will be building your web applications with a code base that is easy to maintain.</p>
<p>If you want to dive deep into DOM manipulation, <a target="_blank" href="https://www.freecodecamp.org/news/the-javascript-dom-manipulation-handbook/">I wrote a whole handbook</a> that covers the subject in depth.</p>
<p>Thanks for reading. And happy coding! For more in-depth tutorials, feel free to <a target="_blank" href="https://www.youtube.com/@DevAfterHours">subscribe to my YouTube channel</a></p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Understanding DOM Events and JavaScript Event Listeners ]]>
                </title>
                <description>
                    <![CDATA[ JavaScript code in the browser uses an event-driven programming pattern. What this means is that when a specific DOM event happens in the browser, a piece of code will be executed as a response to that action. In this article, I will help you see and... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/dom-events-and-javascript-event-listeners/</link>
                <guid isPermaLink="false">66bd9150abf0ccf74f1ce9b2</guid>
                
                    <category>
                        <![CDATA[ DOM ]]>
                    </category>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Nathan Sebhastian ]]>
                </dc:creator>
                <pubDate>Wed, 10 Jan 2024 20:38:04 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2024/01/DOM-events-feature-image.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>JavaScript code in the browser uses an event-driven programming pattern. What this means is that when a specific DOM event happens in the browser, a piece of code will be executed as a response to that action.</p>
<p>In this article, I will help you see and understand how to listen and respond to DOM events using JavaScript.</p>
<p>If you need a refresher on the DOM, I have written an article that explains <a target="_blank" href="https://www.freecodecamp.org/news/introduction-to-the-dom/">what the DOM is and how JavaScript interacts with it</a>.</p>
<h2 id="heading-what-are-dom-events-and-why-are-they-useful">What Are DOM Events and Why Are They Useful?</h2>
<p>DOM events are signals exposed by the browser that you can use to run a piece of JavaScript code.</p>
<p>These DOM events occur when the user interacts with the application we've created, such as clicking a button or typing letters into an input field.</p>
<p>As a web developer, you can instruct JavaScript to listen for a specific event and do something in response to that event.</p>
<p>For example:</p>
<ul>
<li>When <strong>a button</strong> is clicked, do <strong>change the</strong> text <strong>of</strong> a paragraph.</li>
<li>When <strong>a form is submitted</strong>, do <strong>a POST request using the Fetch API.</strong></li>
</ul>
<p>In this article, I will help you see and understand how to listen and respond to DOM events using JavaScript.</p>
<h2 id="heading-how-to-listen-to-dom-events">How to Listen to DOM Events</h2>
<p>To listen for an event, you need to attach an event listener to an element by using the <code>addEventListener()</code> method.</p>
<p>The <code>addEventListener()</code> method accepts two parameters:</p>
<ol>
<li>The event <code>type</code> to listen to</li>
<li>A function to run when the event is triggered</li>
</ol>
<pre><code class="lang-js">Element.addEventListener(type, <span class="hljs-function"><span class="hljs-keyword">function</span>);</span>
</code></pre>
<p>Back to the example, suppose you want to change the text of a paragraph when a <code>button</code> element is clicked. Here’s how you do it:</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">body</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">p</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"myParagraph"</span>&gt;</span>This is an example paragraph<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"changeText"</span>&gt;</span>Change Text<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">script</span>&gt;</span><span class="javascript">
    <span class="hljs-keyword">const</span> button = <span class="hljs-built_in">document</span>.querySelector(<span class="hljs-string">'#changeText'</span>);

    <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">newText</span>(<span class="hljs-params">event</span>) </span>{
      <span class="hljs-keyword">const</span> p = <span class="hljs-built_in">document</span>.querySelector(<span class="hljs-string">'#myParagraph'</span>);
      p.innerText = <span class="hljs-string">'The text has been changed'</span>;
    }

    button.addEventListener(<span class="hljs-string">'click'</span>, newText);
  </span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">body</span>&gt;</span>
</code></pre>
<p>To insert JavaScript code into the HTML document, we need to use the <code>script</code> tag as shown above.</p>
<p>The button element is selected using <code>document.querySelector()</code> method, then the method <code>addEventListener()</code> is called on the element. This means you attach an event listener to the button.</p>
<p>First, you specify the <code>type</code> of event to listen to, which is a <code>click</code> event in this case. Next, you specify the function to run when that event happens.</p>
<p>In the code above, the <code>newText</code> function will be executed when the <code>click</code> event is triggered.</p>
<p>The event listener will also send an <code>event</code> object, which carries information about the event that was triggered. That’s why there’s an <code>event</code> parameter in the <code>newText</code> function above.</p>
<p>You can log the event to the console to see its details:</p>
<pre><code class="lang-js"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">newText</span>(<span class="hljs-params">event</span>) </span>{
  <span class="hljs-built_in">console</span>.log(event);
}
</code></pre>
<p>If you click on the button again, you will have the following output:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/01/event-log-example-1.png" alt="Event object log" width="600" height="400" loading="lazy">
<em>An example Event object log</em></p>
<p>Depending on what you want to do when an event is triggered, you may need to use the information contained inside the <code>event</code> object.</p>
<p>Here, all we want to do is to change the text of the paragraph, so the <code>event</code> object is not needed. We’ll see an example of using the <code>event</code> object later, when handling the keyboard events.</p>
<p>There are many events you can listen to in the browser. Here are some of the most common events you may need when developing a web application:</p>
<table><tbody><tr><td>Event</td><td>Event is fired</td></tr><tr><td>click</td><td>When you press down and release the primary mouse button. Used to track buttons and clickable elemennts</td></tr><tr><td>mousemove</td><td>When you move the mouse cursor</td></tr><tr><td>mouseover</td><td>When you move the mouse cursor over an element. It's like the CSS hover state</td></tr><tr><td>mouseout</td><td>When your mouse cursor moves outside the boundaries of an element</td></tr><tr><td>dblclick</td><td>When you click twice</td></tr><tr><td>DOMContentLoaded</td><td>When the DOM content is fully loaded</td></tr><tr><td>keydown</td><td>When you press a key on your keyboard</td></tr><tr><td>keyup</td><td>When you release a key on your keyboard</td></tr><tr><td>submit</td><td>When a form is submitted</td></tr></tbody></table>

<p>If you want to read the full list of DOM event types, you can <a target="_blank" href="https://en.wikipedia.org/wiki/DOM_event">visit this page</a>.</p>
<p>The DOM Events are broken into several categories. Here we will just look at two of the most common events you might use in your project: keyboard and mouse events.</p>
<h2 id="heading-keyboard-events">Keyboard Events</h2>
<p>For the keyboard, you can track the <code>keydown</code> and <code>keyup</code> events, which run when you press and release a key, respectively.</p>
<p>To show you an example, run the following code from the console:</p>
<pre><code class="lang-js"><span class="hljs-built_in">document</span>.addEventListener(<span class="hljs-string">'keydown'</span>, <span class="hljs-function"><span class="hljs-params">event</span> =&gt;</span> {
  <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`A key is pressed: <span class="hljs-subst">${event.key}</span>`</span>);
});

<span class="hljs-built_in">document</span>.addEventListener(<span class="hljs-string">'keyup'</span>, <span class="hljs-function"><span class="hljs-params">event</span> =&gt;</span> {
  <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`A key is released: <span class="hljs-subst">${event.key}</span>`</span>);
});
</code></pre>
<p>Once you run the code above, press a key on your keyboard slowly, then release it slowly.</p>
<p>You should see a log output as follows:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/01/keydown-event-1.png" alt="Keyboard events log" width="600" height="400" loading="lazy">
<em>Logging keyup and keydown events</em></p>
<p>Notice how the 'keydown' log appears as soon as you press a key, and the 'keyup' log appears only when you release the key.</p>
<p>The keyboard events are usually attached to the <code>document</code> object instead of a specific element, because the whole website should be able to listen to that event.</p>
<h2 id="heading-mouse-events">Mouse Events</h2>
<p>Aside from keyboard events, the DOM also provides a way to track any mouse events.</p>
<p>The most common mouse events that you can track are:</p>
<ul>
<li><code>mousedown</code> – the mouse button was pressed</li>
<li><code>mouseup</code> – the mouse button was released </li>
<li><code>click</code> – a click event </li>
<li><code>dblclick</code> – a double click event </li>
<li><code>mousemove</code> – when the mouse is moved over the element </li>
<li><code>contextmenu</code> – when the context menu is opened, for example on a right mouse button click</li>
</ul>
<p>Again, you can test these events by adding an event listener directly to the <code>document</code> object:</p>
<pre><code class="lang-js"><span class="hljs-built_in">document</span>.addEventListener(<span class="hljs-string">'mousedown'</span>, <span class="hljs-function"><span class="hljs-params">event</span> =&gt;</span> {
  <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`The mouse is pressed`</span>);
});

<span class="hljs-built_in">document</span>.addEventListener(<span class="hljs-string">'mouseup'</span>, <span class="hljs-function"><span class="hljs-params">event</span> =&gt;</span> {
  <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`The mouse is released`</span>);
});
</code></pre>
<p>Run the code above, then click anywhere inside the browser. You should see the <code>mousedown</code> and <code>mouseup</code> events logged, respectively.</p>
<h2 id="heading-how-to-remove-event-listeners">How to Remove Event Listeners</h2>
<p>To remove an event listener attached to an element, you need to call the <code>removeEventListener()</code> method, passing the <code>type</code> of the event and the <code>function</code> you passed to the <code>addEventListener()</code> method as follows:</p>
<pre><code class="lang-js">button.removeEventListener(<span class="hljs-string">'click'</span>, newText);
</code></pre>
<p>The above code is enough to remove the 'click' event listener from the <code>button</code> element. Notice how you need to call the <code>removeEventListener()</code> method on the element while also passing the function <code>newText</code> to the method.</p>
<p>To correctly remove an event listener, you need to have a reference to the function attached to the event. If you pass a nameless function to the <code>addEventListener()</code> method, then that event can’t be removed:</p>
<pre><code class="lang-js">button.addEventListener(<span class="hljs-string">'click'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">event</span>) </span>{
  alert(<span class="hljs-string">'Button save is clicked'</span>);
});
</code></pre>
<p>Without the function name as in the example above, you won’t be able to remove the event listener.</p>
<h2 id="heading-how-to-listen-to-events-using-html-attributes">How to Listen to Events using HTML Attributes</h2>
<p>Aside from using the <code>addEventListener()</code> method, you can also listen to events by adding the <code>on[eventname]</code> attribute to your HTML elements.</p>
<p>For example, suppose you want to listen to a button click. You can add the <code>onclick</code> attribute to your button as follows:</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">body</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">onclick</span>=<span class="hljs-string">"handleClick()"</span>&gt;</span>Click Me!<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">script</span>&gt;</span><span class="javascript">

    <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">handleClick</span>(<span class="hljs-params">event</span>) </span>{
      alert(<span class="hljs-string">'The button is clicked!'</span>);
    }
  </span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">body</span>&gt;</span>
</code></pre>
<p>In the button element above, we add the <code>onclick</code> property and pass the <code>handleClick()</code> function to it. </p>
<p>When we click on the button, the <code>handleClick()</code> function will be executed.</p>
<p>You can also add the <code>onclick</code> attribute using JavaScript as follows:</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">body</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"myBtn"</span>&gt;</span>Click Me!<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">script</span>&gt;</span><span class="javascript">
    <span class="hljs-keyword">const</span> myBtn = <span class="hljs-built_in">document</span>.querySelector(<span class="hljs-string">'#myBtn'</span>);
    myBtn.onclick = handleClick;

    <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">handleClick</span>(<span class="hljs-params">event</span>) </span>{
      alert(<span class="hljs-string">'The button is clicked!'</span>);
    }
  </span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">body</span>&gt;</span>
</code></pre>
<p>Here, we assign a reference to the <code>handleClick</code> function to the <code>onclick</code> property using JavaScript.</p>
<p>To remove the onclick attribute, you can assign the property to null:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> myBtn = <span class="hljs-built_in">document</span>.querySelector(<span class="hljs-string">'#myBtn'</span>);
myBtn.onclick = <span class="hljs-literal">null</span>;
</code></pre>
<h2 id="heading-which-one-should-you-use">Which One Should You Use?</h2>
<p>As you can see, there are two ways you can listen to DOM events: the <code>addEventListener()</code> method and the <code>on[eventname]</code> HTML attribute. Which one should you use? </p>
<p>The answer is that the <code>addEventListener()</code> method can be used when you need more extensibility, and the <code>on[eventname]</code> can be used when you prefer things to be simple.</p>
<p>When developing web applications, the <code>.html</code> file should only serve as the structure of the page, while the <code>.js</code> file should define any behavior the web application can have.</p>
<p>To make your application easier to maintain and extend, JavaScript should have access to HTML elements, but no HTML elements should be able to execute JavaScript functions. This is why <code>addEventListener()</code> should be the recommended method.</p>
<p>But <code>addEventListener()</code> doesn't come without a cost: you trade extensibility with verbosity, making your code quite cumbersome to read.</p>
<p>When using the <code>on[eventname]</code> attribute, you only need to specify the function name in your HTML element:</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">body</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">onclick</span>=<span class="hljs-string">"handleClick()"</span>&gt;</span>Click Me!<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">script</span>&gt;</span><span class="javascript">

    <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">handleClick</span>(<span class="hljs-params">event</span>) </span>{
      alert(<span class="hljs-string">'The button is clicked!'</span>);
    }
  </span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">body</span>&gt;</span>
</code></pre>
<p>But when you use the <code>addEventListener()</code> method, you need to query the element you need, call the method, then specify the event and the callback function to run:</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">body</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"myBtn"</span>&gt;</span>Click Me!<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">script</span>&gt;</span><span class="javascript">
    <span class="hljs-keyword">const</span> myBtn = <span class="hljs-built_in">document</span>.querySelector(<span class="hljs-string">'#myBtn'</span>);
    myBtn.addEventListener(<span class="hljs-string">'click'</span>, handleClick);

    <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">handleClick</span>(<span class="hljs-params">event</span>) </span>{
      alert(<span class="hljs-string">'The button is clicked!'</span>);
    }
  </span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">body</span>&gt;</span>
</code></pre>
<p>As you can see above, there are two additional lines that you don't need to write when you use the <code>on[eventname]</code> attribute. </p>
<p>While it might look insignificant, it will be a serious issue when you work on a large scale application with many HTML and JS files.</p>
<p>In addition, the <code>addEventListener()</code> method also allows you to attach multiple listeners to the same element as follows:</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">body</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"myBtn"</span>&gt;</span>Click Me!<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">script</span>&gt;</span><span class="javascript">
    <span class="hljs-keyword">const</span> myBtn = <span class="hljs-built_in">document</span>.querySelector(<span class="hljs-string">'#myBtn'</span>);

    myBtn.addEventListener(<span class="hljs-string">'click'</span>, handleClick);

    myBtn.addEventListener(<span class="hljs-string">'click'</span>, handleClickTwo);

    <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">handleClick</span>(<span class="hljs-params"></span>) </span>{
      <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'Run from handleClick function'</span>);
    }

    <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">handleClickTwo</span>(<span class="hljs-params"></span>) </span>{
      <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'Run from handleClickTwo function'</span>);
    }
  </span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">body</span>&gt;</span>
</code></pre>
<p>When you click on the button above, JavaScript will execute both event listeners.</p>
<p>This is not possible with the <code>onclick</code> property because you can only assign one function as a reference at a time:</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">body</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"myBtn"</span>&gt;</span>Click Me!<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">script</span>&gt;</span><span class="javascript">
    <span class="hljs-keyword">const</span> myBtn = <span class="hljs-built_in">document</span>.querySelector(<span class="hljs-string">'#myBtn'</span>);

    myBtn.onclick = handleClick;

    <span class="hljs-comment">// when you assign a new function to onclick,</span>
    <span class="hljs-comment">// the old function is overwritten</span>

    myBtn.onclick = handleClickTwo;

    <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">handleClick</span>(<span class="hljs-params"></span>) </span>{
      <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'Run from handleClick function'</span>);
    }

    <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">handleClickTwo</span>(<span class="hljs-params"></span>) </span>{
      <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'Run from handleClickTwo function'</span>);
    }
  </span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">body</span>&gt;</span>
</code></pre>
<p>But I never encountered a situation where I needed to listen to the same event twice, so this advantage might not be useful at all.</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>The DOM events exposed by the browser enable you to respond to user actions in the appropriate way. </p>
<p>This pattern of using event listeners to do specific tasks is known as event-driven programming, and you'll use this pattern a lot when developing a web application using JavaScript.</p>
<p>There are two ways you can listen to events: using the <code>addEventListener()</code> JavaScript method and the <code>on[eventname]</code> HTML attributes. Each has its advantages and disadvantages, so it's good to be familiar with both.</p>
<p>If you enjoyed this article and want to take your JavaScript skills to the next level, I recommend you check out my new book <em>Beginning Modern JavaScript</em> <a target="_blank" href="https://codewithnathan.com/beginning-modern-javascript">here</a>.</p>
<p><a target="_blank" href="https://codewithnathan.com/beginning-modern-javascript"><img src="https://www.freecodecamp.org/news/content/images/2024/01/beginning-js-cover.png" alt="beginning-js-cover" width="600" height="400" loading="lazy"></a></p>
<p>The book is designed to be easy for beginners and accessible to anyone looking to learn JavaScript. It provides a step-by-step gentle guide that will help you understand how to use JavaScript to create a dynamic web application.</p>
<p>Here's my promise: <em>You will actually feel like you understand what you're doing with JavaScript.</em></p>
<p>Until next time!</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ What is the Document Object Model? DOM for Beginners ]]>
                </title>
                <description>
                    <![CDATA[ In this article, I'm going to explain to you how the DOM works so that you have a clear picture of why JavaScript is needed to develop a web application. First, let's recap what we know about HTML, CSS, and JavaScript. How HTML, CSS, and JavaScript w... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/introduction-to-the-dom/</link>
                <guid isPermaLink="false">66bd9167621c718d60a31069</guid>
                
                    <category>
                        <![CDATA[ DOM ]]>
                    </category>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Web Development ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Nathan Sebhastian ]]>
                </dc:creator>
                <pubDate>Wed, 10 Jan 2024 15:14:00 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2024/01/dom-introduction-feature-image-1.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>In this article, I'm going to explain to you how the DOM works so that you have a clear picture of why JavaScript is needed to develop a web application.</p>
<p>First, let's recap what we know about HTML, CSS, and JavaScript.</p>
<h2 id="heading-how-html-css-and-javascript-work">How HTML, CSS, and JavaScript work</h2>
<p>When you want to build a web application, you create an HTML document filled with HTML, CSS, and JavaScript.</p>
<p>These three technologies are used together like a team, each playing a different role in building what you see in your web browser.</p>
<p>HTML is a markup language used to define the structure and content of the page. The tags we use like <code>&lt;head&gt;</code>, <code>&lt;body&gt;</code>, and <code>&lt;button&gt;</code> have meanings, and the browser will process these tags, rendering the content of the document to the screen</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/01/9-just-html.png" alt="9 just html" width="600" height="400" loading="lazy">
<em>What an HTML-only website looks like</em></p>
<p>But the HTML alone produces a very boring and generic-looking page. CSS was created to enable us to change the way the HTML tags are represented on the browser.</p>
<p>By using CSS, you can make a button displayed in a color of your choice, or a text input box with a rounded border, making them more appealing and modern.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/01/9-html-and-css-1.png" alt="9 html and css" width="600" height="400" loading="lazy">
<em>A Website styled with CSS looks appealing and modern</em></p>
<p>HTML and CSS are great partners, but even then, a web page is still just a passive thing. Once the browser processes the content and renders it, you can’t edit the page in any way.</p>
<p>You can’t change the background and text color of the page (like switching to dark mode, for example). You can’t create cool animations, turn on the microphone or webcam, or retrieve data from another website to display on the page after a click.</p>
<p>JavaScript is the programming language that’s supported by the browser, and it fills this gap left open by HTML and CSS.</p>
<p>In short, JavaScript breathes life into static websites, turning them dynamic. It allows a website to interact with the user, respond to their actions, and dynamically update the content without requiring a page reload.</p>
<h2 id="heading-the-dom-explained">The DOM Explained</h2>
<p>So how come JavaScript can do things that HTML and CSS can’t do? Well, the answer is that JavaScript can manipulate the Document Object Model, or the DOM for short.</p>
<p>The DOM is a hierarchical structure composed of objects that make up a web page. Web browsers then expose this DOM so that you can change the page structure, style, and content using JavaScript.</p>
<p>For example, suppose you have the following HTML content in your document:</p>
<pre><code class="lang-html"><span class="hljs-meta">&lt;!DOCTYPE <span class="hljs-meta-keyword">html</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">html</span> <span class="hljs-attr">lang</span>=<span class="hljs-string">"en"</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">head</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">charset</span>=<span class="hljs-string">"UTF-8"</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"viewport"</span> <span class="hljs-attr">content</span>=<span class="hljs-string">"width=device-width, initial-scale=1.0"</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">title</span>&gt;</span>Document<span class="hljs-tag">&lt;/<span class="hljs-name">title</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">head</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">body</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">h1</span>&gt;</span>Hello World!<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>This is a paragraph element<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">body</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">html</span>&gt;</span>
</code></pre>
<p>The DOM graph generated by the HTML document above is as follows. I’m going to explain what the graph means below:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/01/9-dom-example.png" alt="9 dom example" width="600" height="400" loading="lazy">
<em>Example of the DOM tree graph</em></p>
<p>The DOM looks like a tree structure with a set of connected nodes. These nodes are objects that you can access using JavaScript. The <code>html</code> node and its children are the content of your document.</p>
<p>For now, let’s focus on the <code>window</code> and <code>document</code> objects.</p>
<h2 id="heading-the-window-object">The Window Object</h2>
<p>The <code>window</code> object is the root of the DOM tree, and this object is used to instruct the browser to do tasks like:</p>
<ul>
<li>Displaying an alert box or a prompt</li>
<li>Log messages or errors to the console</li>
<li>Access the browser’s local storage</li>
<li>Access the document object</li>
</ul>
<p>You can access the window object from the Console by typing <code>window</code> and pressing Enter. The browser will respond by showing you the methods and properties of the object as follows:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/01/9-window.png" alt="9 window" width="600" height="400" loading="lazy">
<em>The Window object properties and methods</em></p>
<p>The <code>window</code> object provides both child objects and methods that you’re going to access to manipulate a web page.</p>
<p>For example, the <code>window</code> has the <code>console</code> object that you can use to log a message to the console.</p>
<p>Type the code below to the console and hit Enter:</p>
<pre><code class="lang-js"><span class="hljs-built_in">window</span>.console.log(<span class="hljs-string">'Hello World!'</span>);
</code></pre>
<p>You’ll see the string 'Hello World!' logged into the console.</p>
<p>The <code>window</code> object is a global object, so you can omit it when calling its child object. To access the <code>console</code> object, just type console as follows:</p>
<pre><code class="lang-js"><span class="hljs-built_in">console</span>.log(<span class="hljs-string">'Hello World!'</span>);
</code></pre>
<p>The same goes for when you access the <code>document</code> object. You can write <code>document.propertyOrMethod</code> instead of <code>window.document.propertyOrMethod</code>.</p>
<p>I won’t go too deep on the <code>window</code> object, because as a web developer, you’re going to interact more with the <code>document</code> object in your daily routine.</p>
<h2 id="heading-the-document-object">The Document Object</h2>
<p>The <code>document</code> object is the entry point for all HTML elements that you write in your document. This object is also what gives the Document Object Model its name.</p>
<p>It’s not called the Window Object Model because we’re mostly going to work with the Document object instead of the Window object.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/01/9-dom-example-html.png" alt="9 dom example html" width="600" height="400" loading="lazy">
<em>The Document Object is the child of the Window object</em></p>
<p>From the document object, you can retrieve any data related to the HTML content using JavaScript. </p>
<p>For example, you can get the Document title using the <code>document.title</code> property, and the URL using <code>document.URL</code>. The referrer is available in <code>document.referrer</code>, the domain in <code>document.domain</code>.</p>
<p>For the HTML document itself, you can access the whole HTML Element node using <code>document.documentElement</code>, the document head using the <code>document.head</code> property, or the body using <code>document.body</code></p>
<p>You can try to access these elements from the console as shown below:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/01/9-document-properties.png" alt="9 document properties" width="600" height="400" loading="lazy">
<em>documentElement, head, and body properties of the Document object</em></p>
<p>You can see the documentation of all the properties and methods of the document object <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/API/Document">here</a> (note that it might be overwhelming at first).</p>
<p>Of course, you can do much more than just read your document data. I've written another article that shows you <a target="_blank" href="https://www.freecodecamp.org/news/javascript-document-object-model-explained/">how to manipulate the DOM using JavaScript</a>.</p>
<h2 id="heading-summary">Summary</h2>
<p>The DOM is a tree-like structure generated from the HTML file that we created and loaded into the browser.</p>
<p>The browser then exposes this DOM as a set of JavaScript objects that we can access, such as the <code>window</code> and <code>document</code> objects.</p>
<p>It’s an important piece of technology that allows you to program the web browser to do specific tasks or change your HTML content.</p>
<p>If you enjoyed this article and want to take your JavaScript skills to the next level, I recommend you check out my new book <em>Beginning Modern JavaScript</em> <a target="_blank" href="https://codewithnathan.com/beginning-modern-javascript">here</a>.</p>
<p><a target="_blank" href="https://codewithnathan.com/beginning-modern-javascript"><img src="https://www.freecodecamp.org/news/content/images/2024/01/beginning-js-cover.png" alt="beginning-js-cover" width="600" height="400" loading="lazy"></a></p>
<p>The book is designed to be easy for beginners and accessible to anyone looking to learn JavaScript. It provides a step-by-step gentle guide that will help you understand how to use JavaScript to create a dynamic web application.</p>
<p>Here's my promise: <em>You will actually feel like you understand what you're doing with JavaScript.</em></p>
<p>Until next time!</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ The JavaScript DOM Manipulation Handbook ]]>
                </title>
                <description>
                    <![CDATA[ DOM Manipulation is one of the most exciting topics to learn about in JavaScript. This is because one of JavaScript's main uses is to make web pages interactive – and the Document Object Model (DOM) plays a major role in this. The DOM is a powerful t... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/the-javascript-dom-manipulation-handbook/</link>
                <guid isPermaLink="false">66d45deb182810487e0ce114</guid>
                
                    <category>
                        <![CDATA[ DOM ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Front-end Development ]]>
                    </category>
                
                    <category>
                        <![CDATA[ handbook ]]>
                    </category>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Web Development ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Benjamin Semah ]]>
                </dc:creator>
                <pubDate>Wed, 10 Jan 2024 15:12:57 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2024/01/The-JavaScript-DOM-Manipulation-Handbook-Cover.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>DOM Manipulation is one of the most exciting topics to learn about in JavaScript. This is because one of JavaScript's main uses is to make web pages interactive – and the Document Object Model (DOM) plays a major role in this.</p>
<p>The DOM is a powerful tool that allows you to interact with and manipulate the elements on a web page. And this handbook will help you understanding and become confident in working with it.</p>
<p>You will begin by learning what the DOM is and what you can do with it. Then we'll dive into how to select, modyfy, and style DOM elements. You will also learn how to create new elements and add them to your web page.</p>
<p>The handbook also cover topics like how to traverse the DOM what DOM events are, and includes some project ideas for practice.</p>
<p>Let's get started!</p>
<h2 id="heading-table-of-contents">Table of Contents</h2>
<ul>
<li><p><a class="post-section-overview" href="#what-is-the-dom">What is the DOM?</a></p>
<ul>
<li><a class="post-section-overview" href="#what-you-can-do-with-the-dom">What you can do with the DOM</a></li>
</ul>
</li>
<li><p><a class="post-section-overview" href="#how-to-select-dom-elements">How to Select DOM Elements</a></p>
<ul>
<li><p><a class="post-section-overview" href="#1-getelementbyid">getElementById</a></p>
</li>
<li><p><a class="post-section-overview" href="#2-getelementsbyclassname">getElementsByClassName</a></p>
</li>
<li><p><a class="post-section-overview" href="#3-getelementsbytagname">getElementsByTagName</a></p>
</li>
<li><p><a class="post-section-overview" href="#4-queryselector">querySelector</a></p>
</li>
<li><p><a class="post-section-overview" href="#5-queryselectorall">querySelectorAll</a></p>
</li>
</ul>
</li>
<li><p><a class="post-section-overview" href="#how-to-change-the-content-of-dom-elements">How to Change the Content of DOM Elements</a></p>
<ul>
<li><p><a class="post-section-overview" href="#the-innerhtml-property">The innerHTML Property</a></p>
</li>
<li><p><a class="post-section-overview" href="#security-risks-with-innerhtml">Security Risks with innerHTML</a></p>
</li>
<li><p><a class="post-section-overview" href="#the-innertext-and-textcontent-properties">The innerText and textContent Properties</a></p>
</li>
</ul>
</li>
<li><p><a class="post-section-overview" href="#how-to-work-with-attributes-of-dom-elements">How to Work with Attributes of DOM Elements</a></p>
<ul>
<li><p><a class="post-section-overview" href="#the-getattribute-method">The getAttribute Method</a></p>
</li>
<li><p><a class="post-section-overview" href="#the-setattribute-method">The setAttribute Method</a></p>
</li>
<li><p><a class="post-section-overview" href="#the-removeattribute-method">The removeAttribute Method</a></p>
</li>
<li><p><a class="post-section-overview" href="#the-hasattribute-method">The hasAttribute Method</a></p>
</li>
</ul>
</li>
<li><p><a class="post-section-overview" href="#how-to-change-the-styles-on-dom-elements">How to Change the Styles on DOM Elements</a></p>
<ul>
<li><p><a class="post-section-overview" href="#setting-styles-with-the-style-property">Setting Styles with the .style Property</a></p>
</li>
<li><p><a class="post-section-overview" href="#setting-styles-with-classes">Setting Styles with Classes</a></p>
</li>
</ul>
</li>
<li><p><a class="post-section-overview" href="#how-to-traverse-the-dom">How to Traverse the DOM</a></p>
<ul>
<li><p><a class="post-section-overview" href="#difference-between-a-node-and-an-element">Difference Between a Node and an Element</a></p>
</li>
<li><p><a class="post-section-overview" href="#selecting-a-parent-with-parentnode-vs-parentelement">Selecting a Parent with parentNode vs parentElement</a></p>
</li>
<li><p><a class="post-section-overview" href="#selecting-elements-with-childnodes-vs-children">Selecting Elements with childNodes vs children</a></p>
</li>
<li><p><a class="post-section-overview" href="#selecting-the-first-or-last-child-element">Selecting the First or Last Child/Element</a></p>
</li>
<li><p><a class="post-section-overview" href="#selecting-a-sibling-of-nodes-in-the-dom">Selecting a Sibling of Nodes in the DOM</a></p>
</li>
</ul>
</li>
<li><p><a class="post-section-overview" href="#dom-events-and-event-listeners">DOM Events and Event Listeners</a></p>
<ul>
<li><p><a class="post-section-overview" href="#difference-between-event-listener-and-event-handler">Difference Between Event Listener and Event Handler</a></p>
</li>
<li><p><a class="post-section-overview" href="#three-ways-to-register-events-in-javascript">Three Ways to Register Events in JavaScript</a></p>
</li>
<li><p><a class="post-section-overview" href="#practice-challenge">Practice Challenge</a></p>
</li>
<li><p><a class="post-section-overview" href="#solution-to-practice-challenge">Solution to Practice Challenge</a></p>
</li>
<li><p><a class="post-section-overview" href="#the-event-object">The Event Object</a></p>
</li>
<li><p><a class="post-section-overview" href="#types-of-events">Types of Events</a></p>
</li>
</ul>
</li>
<li><p><a class="post-section-overview" href="#event-flow-in-javascript">Event Flow in JavaScript</a></p>
<ul>
<li><p><a class="post-section-overview" href="#event-bubbling">Event Bubbling</a></p>
</li>
<li><p><a class="post-section-overview" href="#event-capturing">Event Capturing</a></p>
</li>
<li><p><a class="post-section-overview" href="#the-event-stoppropagation-method">The Event stopPropagation Method</a></p>
</li>
</ul>
</li>
<li><p><a class="post-section-overview" href="#js-dom-manipulation-project-ideas">JS DOM Manipulation Projects Ideas</a></p>
</li>
<li><p><a class="post-section-overview" href="#conclusion">Conclusion</a></p>
</li>
</ul>
<h2 id="heading-what-is-the-dom">What is the DOM?</h2>
<p>DOM stands for Document Object Model. But what does that mean? Let's break it down.</p>
<p>The <strong>Document</strong> part refers to the webpage you see in the browser. Specifically, the HTML Document which handles the structure of the page's content. This includes the text, images, links, and other elements that make up the page.</p>
<p><strong>Object</strong> means the elements like images, headers, and paragraphs are treated like objects. Each object has its properties (like id, class, style) and methods. Using these properties and methods, you can manipulate the elements.</p>
<p>The <strong>Model</strong> in DOM means it's a representation or copy of the HTML document as a hierarchical tree. This tree includes all the elements. And it captures the parent-child relationships between them.</p>
<p>The DOM is always identical to the HTML document. Browsers ensure that they are in sync. So if something changes in the HTML, the DOM changes too, and vice versa.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/01/JavaScript--2-.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>A graphical representation of the HTML DOM tree</em></p>
<p>At the top of the hierarchy is the Document object. It has only one child – the <code>html</code> element. The <code>html</code> element, also known as the root element, has two children, the <code>head</code> and <code>body</code> elements. And each of them also have their own children elements.</p>
<p>The parent-child relationship between the elements is what allows you to traverse or move between and select them. More on that later.</p>
<h3 id="heading-what-you-can-do-with-the-dom">What You Can Do With the DOM</h3>
<p>DOM manipulation allows developers to interact with the structure, style, and content of web pages. The following are some of the things you can do with the DOM:</p>
<ul>
<li><p>Change and remove existing elements in the DOM.</p>
</li>
<li><p>Create and add new elements to the page.</p>
</li>
<li><p>Change the styles for elements.</p>
</li>
<li><p>Add event listeners to the elements to make them interactive.</p>
</li>
</ul>
<h2 id="heading-how-to-select-dom-elements">How to Select DOM Elements</h2>
<p>To do something with DOM elements, you first have to select or access the element in question. In this section, you will learn some common methods for selecting DOM elements.</p>
<p>Let's use the following phonebook markup to show how the various DOM selector methods work.</p>
<pre><code class="lang-html">  <span class="hljs-tag">&lt;<span class="hljs-name">h1</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"page-title"</span>&gt;</span>Phonebook<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span>

  <span class="hljs-tag">&lt;<span class="hljs-name">p</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"family"</span>&gt;</span>Marie<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">p</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"family"</span>&gt;</span>Jose<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">p</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"work"</span>&gt;</span>Anne<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">p</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"work"</span>&gt;</span>Joan<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
</code></pre>
<p>The markup includes a header with an id of <code>page-title</code> and four paragraphs. The first two paragraphs both have a class of <code>family</code>, and the last two have a class of <code>work</code>.</p>
<h3 id="heading-1-getelementbyid">1. getElementById</h3>
<p>You use this method to select elements with an id attribute. Ids are unique identifiers. For example, if a header element has an id attribute with a value of "page-title", no other element on the page should also have an id with the same value.</p>
<p>This means anytime you use the <code>getElementById</code> method, you are going to select only one element from the DOM.</p>
<p>Let's look at an example:</p>
<p>The <code>h1</code> header has an id value of <code>page-title</code>. Here is how you can select it using the <code>getElementById</code> method:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> titleElement = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">"page-title"</span>)
<span class="hljs-built_in">console</span>.log(titleElement)
</code></pre>
<p>The example selects the header element and assigns it to the <code>titleElement</code> variable.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/12/Screenshot-2023-12-02-at-9.01.01-AM.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>Result of accessing element with getElementById method.</em></p>
<p>If there's no element in the DOM with the given id, the <code>getElementById()</code> method will return <code>null</code>.</p>
<h3 id="heading-2-getelementsbyclassname">2. getElementsByClassName</h3>
<p>You can use this method to select more than one object. This method takes in the value of a class attribute as an argument and selects all elements in the DOM that has the given class. Unlike ids, you can give the same class value for different HTML elements.</p>
<p>Here's an example:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> famContacts = <span class="hljs-built_in">document</span>.getElementsByClassName(<span class="hljs-string">"family"</span>)
<span class="hljs-built_in">console</span>.log(famContacts)
</code></pre>
<p>This returns an HTML collection of all elements with the given class. The log statement will print the following in the console:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/12/Screenshot-2023-12-01-at-10.35.51-AM.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>The</em> <code>getElementsByClassName()</code> method returns an HTML collection.</p>
<p>Note: The HTML collection looks like an array, but it is not. You can access the elements using bracket notation just as you would with an array – but you cannot apply array methods like <code>map</code>, <code>filter</code>, and <code>forEach</code> on it.</p>
<pre><code class="lang-javascript"><span class="hljs-built_in">console</span>.log(famContacts[<span class="hljs-number">0</span>])
</code></pre>
<p>This will get the first element in the HTML collection, which is the paragraph with the name Marie.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/12/Screenshot-2023-12-02-at-9.03.35-AM-1.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>Result of accessing HTMLCollection element with bracket notation.</em></p>
<p>But what if you wanted to loop through all the elements in the <code>famContacts</code> HTML collection? You'd first need to convert the HTML collection into an array. Then you could use any of the array methods.</p>
<p>A simple way to create an array from the HTML collection is to use the spread operator, like this:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">let</span> famContactsArray = [...famContacts]

famContactsArray.forEach(<span class="hljs-function"><span class="hljs-params">element</span> =&gt;</span> <span class="hljs-built_in">console</span>.log(element))
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/12/Screenshot-2023-12-02-at-9.06.48-AM.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>A result of logging all elements in the HTMLCollection.</em></p>
<p>Using the <code>forEach</code> method, you can access each of the items in the <code>famContactsArray</code>. The browser will throw an error if you try to apply an array method like <code>map</code> to the HTML collection without first creating an array from it.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/12/Screenshot-2023-12-01-at-11.57.27-AM.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>Error message when you use array methods on an HTMLCollection.</em></p>
<h3 id="heading-3-getelementsbytagname">3. getElementsByTagName</h3>
<p>This method will select elements using their tag name. For example, <code>getElementByTagName('p')</code> will select all paragraphs on the page.</p>
<p>Like <code>getElementsByClassName</code>, this method also returns an HTML collection of the selected elements.</p>
<p>Here's an example:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> allContacts = <span class="hljs-built_in">document</span>.getElementsByTagName(<span class="hljs-string">'p'</span>)
<span class="hljs-built_in">console</span>.log(allContacts)
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/12/Screenshot-2023-12-02-at-8.39.36-AM.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>An HTMLCollection containing all paragraph elements.</em></p>
<p>You can create an array from the HTML collection and use any of the array methods on it.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">let</span> allContactsArray = [...allContacts]

allContactsArray.map(<span class="hljs-function"><span class="hljs-params">element</span> =&gt;</span> <span class="hljs-built_in">console</span>.log(element))
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/12/Screenshot-2023-12-02-at-9.08.26-AM.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>Result of using the map method on</em> <code>allContactsArray</code>.</p>
<h3 id="heading-4-queryselector">4. querySelector</h3>
<p>You can use this method to select any HTML element in the DOM. It returns only one element: the first element that matches the given selector.</p>
<p>The <code>querySelector</code> method works like how CSS selectors work.</p>
<p>For example, what do you do when you want to select an element with an id? You use the hash <code>#</code> symbol. How about when you want to select elements with a class? You put a dot <code>.</code> in front of the class name.</p>
<p>Here's an example:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> firstWorkContact = <span class="hljs-built_in">document</span>.querySelector(<span class="hljs-string">'.work'</span>)
<span class="hljs-built_in">console</span>.log(firstWorkContact)
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/12/Screenshot-2023-12-02-at-11.38.12-AM.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>An example of using the</em> <code>querySelector</code> method.</p>
<p>The example above returns only the first element with a class of <code>work</code> and ignores the rest.</p>
<p>Let's see another example to show how querySelector works like CSS selectors. The following is a <code>div</code> element with four buttons:</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">button</span>&gt;</span>First button<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">button</span>&gt;</span>Second button<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">button</span>&gt;</span>Third button<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">button</span>&gt;</span>Fourth button<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
</code></pre>
<p>Assuming you wanted to select the third button, you could use <code>querySelector</code> like the one below. The code uses the CSS <code>nth-child</code> selector to get the third button inside the div.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> thirdBtn = <span class="hljs-built_in">document</span>.querySelector(<span class="hljs-string">'div button:nth-child(3)'</span>)
<span class="hljs-built_in">console</span>.log(thirdBtn)
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/12/Screenshot-2023-12-02-at-2.42.48-PM.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>Result of selecting the third button with</em> <code>querySelector</code> method.</p>
<p>But what if you want to select all four button elements and not only the first one? Then you could use the <code>querySelectorAll</code> method instead.</p>
<h3 id="heading-5-queryselectorall">5. querySelectorAll</h3>
<p>Like the <code>querySelector</code> method, <code>querySelectorAll</code> also selects HTML elements using CSS selectors. The difference is that it returns all elements that match the selector instead of returning only the first one.</p>
<p>Using the previous example, let's select all the buttons with <code>querySelectorAll</code>.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> allBtns = <span class="hljs-built_in">document</span>.querySelectorAll(<span class="hljs-string">'button'</span>)
<span class="hljs-built_in">console</span>.log(allBtns)
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/12/Screenshot-2023-12-02-at-3.04.18-PM.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>The</em> <code>querySelectorAll</code> method returns a NodeList of selected elements.</p>
<p>Note: <code>querySelectorAll</code> returns a <code>NodeList</code>. A <code>NodeList</code> is slightly different from an HTML collection. You don't need to convert it to an array to apply a method like <code>forEach</code> on it.</p>
<pre><code class="lang-javascript">allBtns.forEach(<span class="hljs-function"><span class="hljs-params">btn</span> =&gt;</span> <span class="hljs-built_in">console</span>.log(btn))
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/12/Screenshot-2023-12-02-at-3.00.19-PM.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>Result of using</em> <code>forEach</code> method on the NodeList.</p>
<p>But you still cannot apply array methods like <code>map</code>, <code>filter</code>, and others on a NodeList. You will need to first create an array from it.</p>
<p>You can read this <a target="_blank" href="https://www.freecodecamp.org/news/dom-manipulation-htmlcollection-vs-nodelist/">freeCodeCamp article on the difference between HTML collection and NodeList</a> to learn more.</p>
<h2 id="heading-how-to-change-the-content-of-dom-elements">How to Change the Content of DOM Elements</h2>
<p>So far you've learned about different ways to select DOM elements. But that is only the beginning. Now, let's see how you can manipulate the DOM to change the content of a webpage.</p>
<p>The first thing you need to do is to select the element. You can do that using any of the methods you learned from the previous section.</p>
<p>After selecting the element, there are several methods you can use to add or update the content.</p>
<h3 id="heading-the-innerhtml-property">The <code>innerHTML</code> Property</h3>
<p>This is a method that allows you to read or update both the structure and content and structure of elements. Let's see an example of how you can use the <code>innerHTML</code> method.</p>
<p>The following is some markup of three paragraphs, each with an id.</p>
<pre><code class="lang-html">  <span class="hljs-tag">&lt;<span class="hljs-name">p</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"topic"</span>&gt;</span>JS array methods<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">p</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"first-method"</span>&gt;</span>map<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">p</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"second-method"</span>&gt;</span>filter<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/12/Screenshot-2023-12-03-at-8.17.55-AM.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>Simple markup with three paragraph elements</em></p>
<p>You can read or get the content of the any of the paragraphs using <code>innerHTML</code>. For example, let's get the content of the first paragraph.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> topicElement = <span class="hljs-built_in">document</span>.querySelector(<span class="hljs-string">'#topic'</span>)
<span class="hljs-built_in">console</span>.log(topicElement.innerHTML)
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/12/Screenshot-2023-12-03-at-8.10.36-AM.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>Log statement of the</em> <code>innerHTML</code> of the <code>topicElement</code></p>
<p>Now, let's say you want to update the topic from "JS array methods" to "JavaScript array methods". You can do that by assigning the new text to the <code>innerHTML</code> of the element.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> topicElement = <span class="hljs-built_in">document</span>.querySelector(<span class="hljs-string">'#topic'</span>)
topicElement.innerHTML = <span class="hljs-string">"JavaScript array methods"</span>
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/12/Screenshot-2023-12-03-at-8.16.59-AM-1.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>The topic is updated from "JS Array methods" to "JavaScript array methods"</em></p>
<p>With <code>innerHTML</code>, you can change more than just the content. You can also change the HTML structure of the element. For example, if you want to make the word "JavaScript" bold, you could do this:</p>
<pre><code class="lang-javascript">topicElement.innerHTML = <span class="hljs-string">"&lt;b&gt;JavaScript&lt;/b&gt; array methods"</span>
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/12/Screenshot-2023-12-03-at-8.27.45-AM.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>The word "JavaScript" is made bold using innerHTML</em></p>
<h3 id="heading-security-risks-with-innerhtml">Security Risks With <code>innerHTML</code></h3>
<p>Using the <code>innerHTML</code> poses potential security risks. An example is <a target="_blank" href="https://www.freecodecamp.org/news/cross-site-scripting-what-is-xss/">cross-site scripting (XSS) attacks</a>.</p>
<p>If the content you're inserting comes from user input or any untrusted source, be sure to validate and sanitize it before using <code>innerHTML</code> to prevent XSS attacks. You can use a library like <a target="_blank" href="https://www.npmjs.com/package/dompurify">DOMPurify</a> to do this.</p>
<p>Also, if you are working with plain text content, consider using methods like <code>innerText</code> and <code>textContent</code>.</p>
<h3 id="heading-the-innertext-and-textcontent-properties">The <code>innerText</code> and <code>textContent</code> Properties</h3>
<p>Both <code>innerText</code> and <code>textContent</code> ignore HTML tags and treat them as part of a string. You can use both methods to read or update the text of DOM elements.</p>
<p>A key difference between the two is in how they treat the text. Using <code>innerText</code> returns the text as it appears on the screen. And using <code>textContent</code> returns text as it appears in the markup. Let's see an example below.</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>Key =<span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">style</span>=<span class="hljs-string">"display: none;"</span>&gt;</span>     ABC123<span class="hljs-tag">&lt;<span class="hljs-name">span</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/12/Screenshot-2023-12-03-at-10.03.41-AM.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>A paragraph element with the some text and a hidden span element inside</em></p>
<p>The example includes a paragraph element. Inside the paragraph is a span that contains a key. The key does not appear on screen because its inline style is set to a display of none.</p>
<p>Now, let's select the paragraph and print both the <code>innerText</code> value and <code>textContent</code> value to see the difference.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> paragraph = <span class="hljs-built_in">document</span>.querySelector(<span class="hljs-string">'p'</span>);

<span class="hljs-built_in">console</span>.log(<span class="hljs-string">"innerText: "</span>, paragraph.innerText)
<span class="hljs-built_in">console</span>.log(<span class="hljs-string">"textContent: "</span>, paragraph.textContent)
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/12/Screenshot-2023-12-03-at-10.06.11-AM.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>Result of log statement for</em> <code>innerText</code> and <code>textContent</code>.</p>
<p>Note how <code>innerText</code> returns the text as it appears on the screen (without the value of the key which is hidden with CSS). And note how <code>textContent</code> returns the text including hidden elements and whitespaces.</p>
<p>Let's see another example for adding text to an element. The following code includes two paragraphs, each with bold text and an empty span, as well as a horizontal line between them.</p>
<pre><code class="lang-html">  <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">b</span>&gt;</span>innerText Example<span class="hljs-tag">&lt;/<span class="hljs-name">b</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"inner-text"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>

  <span class="hljs-tag">&lt;<span class="hljs-name">hr</span>&gt;</span>    

  <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">b</span>&gt;</span>textContent Example<span class="hljs-tag">&lt;/<span class="hljs-name">b</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"textContent"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/12/Screenshot-2023-12-03-at-10.48.11-AM.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>Example to demo the</em> <code>innerText</code> and <code>textContent</code> properties</p>
<p>Now, let's select the two span elements and add the same text to them. This will help you better understand the difference between <code>innerText</code> and <code>textContent</code>.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> example1 = <span class="hljs-built_in">document</span>.querySelector(<span class="hljs-string">'#inner-text'</span>);
<span class="hljs-keyword">const</span> example2 = <span class="hljs-built_in">document</span>.querySelector(<span class="hljs-string">'#text-content'</span>);

<span class="hljs-keyword">let</span> address = <span class="hljs-string">`
  ABC Street,
  Spintex Road,
  Accra,
  Ghana.
`</span>;

example1.innerText = address;
example2.textContent = address;
</code></pre>
<p>The code gives the same variable <code>address</code> to the two examples. The first uses <code>innerText</code> and the second uses <code>textContent</code>. See the results below:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/12/Screenshot-2023-12-03-at-10.46.46-AM.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>Result of updating content with</em> <code>innerText</code> and <code>textContent</code>.</p>
<p>Notice how <code>innerText</code> uses the line breaks but the <code>textContent</code> example doesn't.</p>
<p>Another key difference between the two methods is how they behave when used inside loops. <code>innerText</code> can be slower than <code>textContent</code> when dealing with bulk operations or frequent updates in a loop.</p>
<p><a target="_blank" href="https://www.freecodecamp.org/news/innerhtml-vs-innertext-vs-textcontent/">Read this freeCodeCamp article</a> to learn more about the difference between <code>innerHTML</code>, <code>innerText</code>, and <code>textContent</code>.</p>
<h2 id="heading-how-to-work-with-attributes-of-dom-elements">How to Work with Attributes of DOM Elements</h2>
<p><a target="_blank" href="https://www.freecodecamp.org/news/html-attributes-explained/">HTML attributes</a> provide useful information about HTML elements. These attributes are always included in the opening tag of the element. An attribute is made up of a name and a value (though there are exceptions where only a name is present).</p>
<p>As the browser generates the DOM based on the HTML structure, it translates these attributes into dynamic properties of the DOM objects.</p>
<p>Here's an example:</p>
<p>Assume there's a button in the HTML document with the following attributes:</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"myBtn"</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"submit"</span>&gt;</span>Click Here<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
</code></pre>
<p>For this example, the browser will create an <code>HTMLButtonElement</code> object in the DOM. And the object will have properties matching the attributes.</p>
<ul>
<li><p><code>HTMLButtonElement.id</code> with a value of <code>myBtn</code>.</p>
</li>
<li><p><code>HTMLButtonElement.type</code> with a value of <code>submit</code>.</p>
</li>
</ul>
<p>To interact with and manipulate these attributes using JavaScript, you can use methods like <code>getAttribute</code> and <code>setAttribute</code> to directly access the properties.</p>
<h3 id="heading-the-getattribute-method">The <code>getAttribute</code> Method</h3>
<p>Like the name suggests, you can use this method to get the value of an existing attribute on an element.</p>
<p>It accepts an argument (the name of the attribute) and returns the value of the attribute. If the attribute you passed to it as an argument does not exist on the element, the method will return <code>null</code>.</p>
<p>Here's an example:</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">img</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"image.jpg"</span> <span class="hljs-attr">alt</span>=<span class="hljs-string">"An example image"</span>&gt;</span>
</code></pre>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> imageElement = <span class="hljs-built_in">document</span>.querySelector(<span class="hljs-string">'img'</span>)
<span class="hljs-built_in">console</span>.log(imageElement.getAttribute(<span class="hljs-string">'src'</span>))
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/12/Screenshot-2023-12-09-at-9.00.25-AM.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>The</em> <code>getAttribute</code> method is used to get the value of the <code>src</code> attribute.</p>
<p>Using the <code>getAttribute</code> method is the above example, you can get the value of the <code>src</code> attribute for the image element.</p>
<h3 id="heading-the-setattribute-method">The <code>setAttribute</code> Method</h3>
<p>This is used to set or change the attribute of an element. The method takes in two arguments. The first argument is the name of attribute you want to change, and the second is the new value you want to give the attribute.</p>
<p>Here's an example:</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">img</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"image.jpg"</span> <span class="hljs-attr">alt</span>=<span class="hljs-string">"An example image"</span>&gt;</span>
</code></pre>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> imageElement = <span class="hljs-built_in">document</span>.querySelector(<span class="hljs-string">'img'</span>)

<span class="hljs-built_in">console</span>.log(<span class="hljs-string">"BEFORE:"</span>, imageElement.getAttribute(<span class="hljs-string">'src'</span>))
imageElement.setAttribute(<span class="hljs-string">'src'</span>, <span class="hljs-string">'new-image.jpg'</span>)
<span class="hljs-built_in">console</span>.log(<span class="hljs-string">"AFTER:"</span>, imageElement.getAttribute(<span class="hljs-string">'src'</span>))
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/12/Screenshot-2023-12-09-at-9.27.14-AM.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>The</em> <code>setAttribute</code> method is used to update the value of the <code>src</code> attribute.</p>
<p>This code example logs the value of the <code>src</code> attribute before and after using <code>setAttribute</code> to change it from <code>image.jpg</code> to <code>new-image.jpg</code>.</p>
<p>When you pass an argument to the <code>setAttribute</code> method and that attribute doesn't exit on the element, it will create a new attribute. For example, you can add a height property to the image element like so:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> imageElement = <span class="hljs-built_in">document</span>.querySelector(<span class="hljs-string">'img'</span>)

<span class="hljs-built_in">console</span>.log(<span class="hljs-string">"BEFORE:"</span>, imageElement.getAttribute(<span class="hljs-string">'height'</span>))
imageElement.setAttribute(<span class="hljs-string">'height'</span>, <span class="hljs-string">'200'</span>)
<span class="hljs-built_in">console</span>.log(<span class="hljs-string">"AFTER:"</span>, imageElement.getAttribute(<span class="hljs-string">'height'</span>))
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/12/Screenshot-2023-12-09-at-9.32.53-AM.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>An example of adding a new height attribute to the image element.</em></p>
<p>The first log statement returns <code>null</code> because the height attribute was non-existent. But after setting it with the <code>setAttribute</code> method, the second log statement returns the correct value of the height.</p>
<h3 id="heading-the-removeattribute-method">The <code>removeAttribute</code> Method</h3>
<p>In the previous section, you learned how to add a new attribute using the <code>setAttribute</code> method. What if you wanted to remove an existing attribute?</p>
<p>You can use the <code>removeAttribute</code> method. You pass in the name of the attribute you want to remove from the element as arguments to the method.</p>
<p>Here's an example:</p>
<pre><code class="lang-html">  <span class="hljs-tag">&lt;<span class="hljs-name">img</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"image.jpg"</span> <span class="hljs-attr">alt</span>=<span class="hljs-string">"An example image"</span> <span class="hljs-attr">height</span>=<span class="hljs-string">"200"</span>&gt;</span>
</code></pre>
<p>Let's use the <code>removeAttribute</code> method to remove the <code>height</code> attribute from the image element.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> imageElement = <span class="hljs-built_in">document</span>.querySelector(<span class="hljs-string">'img'</span>)

<span class="hljs-built_in">console</span>.log(<span class="hljs-string">"BEFORE:"</span>, imageElement.getAttribute(<span class="hljs-string">'height'</span>))
imageElement.removeAttribute(<span class="hljs-string">'height'</span>, <span class="hljs-string">'200'</span>)
<span class="hljs-built_in">console</span>.log(<span class="hljs-string">"AFTER:"</span>, imageElement.getAttribute(<span class="hljs-string">'height'</span>))
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/12/Screenshot-2023-12-09-at-10.09.35-AM.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>An example of using the</em> <code>removeAttribute</code> method.</p>
<p>Before using <code>removeAttribute</code>, the first log statement prints the value of the height attribute, <code>200</code>. But after using the <code>removeAttribute</code> method, the second log statement prints <code>null</code>, confirming the removal of the height attribute from the image element.</p>
<h3 id="heading-the-hasattribute-method">The <code>hasAttribute</code> Method</h3>
<p>Another method for working with attributes in the DOM is the <code>hasAttribute</code> method. You can use this method to check whether or not an element has a specific attribute.</p>
<p>The <code>hasAttribute</code> method returns <code>true</code> if the specified attribute exists and returns <code>false</code> if it doesn't.</p>
<p>Here's an example:</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">img</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"image.jpg"</span> <span class="hljs-attr">alt</span>=<span class="hljs-string">"An example image"</span> <span class="hljs-attr">height</span>=<span class="hljs-string">"200"</span>&gt;</span>
</code></pre>
<p>Let's use the <code>hasAttribute</code> to check for the presence of <code>height</code> and <code>width</code> values on the image element.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> imageElement = <span class="hljs-built_in">document</span>.querySelector(<span class="hljs-string">'img'</span>)

<span class="hljs-built_in">console</span>.log(<span class="hljs-string">"HEIGHT"</span>, imageElement.hasAttribute(<span class="hljs-string">'height'</span>))
<span class="hljs-built_in">console</span>.log(<span class="hljs-string">"WIDTH"</span>, imageElement.hasAttribute(<span class="hljs-string">'width'</span>))
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/12/Screenshot-2023-12-09-at-10.20.53-AM.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>Example of using the</em> <code>hasAttribute</code> method to check if an attribute exists.</p>
<p>The check for height returns <code>true</code> because it's an existing attribute while the check for width returns <code>false</code> because it doesn't exist.</p>
<h2 id="heading-how-to-change-the-styles-on-dom-elements">How to Change the Styles on DOM Elements</h2>
<p>There are two main ways of styling elements when working with the DOM in JavaScript. You can use the <code>.style</code> property or you can use classes. Each has its benefits and situations it's best situated for.</p>
<h3 id="heading-setting-styles-with-the-style-property">Setting Styles With the <code>.style</code> Property</h3>
<p>You use the <code>.style</code> property when you want to make specific changes to a single element. The <code>.style</code> property allows you to set styles directly as <a target="_blank" href="https://www.freecodecamp.org/news/inline-style-in-html/">inline styles</a> for elements. This means it overrides the styles you have in your CSS stylesheet.</p>
<p>Using the <code>.style</code> property, you get access to all the individual CSS properties. See the demo below:</p>
<pre><code class="lang-html">  <span class="hljs-tag">&lt;<span class="hljs-name">h1</span>&gt;</span>Styling elements with JavaScript<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span>
</code></pre>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> header = <span class="hljs-built_in">document</span>.querySelector(<span class="hljs-string">'h1'</span>)
<span class="hljs-built_in">console</span>.log(header.style)
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/12/ezgif.com-video-to-gif--8-.gif" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>CSSStyleDeclarations for an</em> <code>h1</code> element logged to the console.</p>
<p>The <code>console.log</code> prints the CSS style declarations with all the CSS properties for that element.</p>
<p>Now, let's see an example of how to use the <code>.style</code> property.</p>
<pre><code class="lang-html">  <span class="hljs-tag">&lt;<span class="hljs-name">h1</span>&gt;</span>I love JavaScript<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span>
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/12/Screenshot-2023-12-11-at-7.56.41-AM.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>An example</em> <code>h1</code> header element</p>
<p>Here is an <code>h1</code> header. Now, let's add style to it using the <code>.style</code> property.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> paragraph = <span class="hljs-built_in">document</span>.querySelector(<span class="hljs-string">'h1'</span>)

paragraph.style.color = <span class="hljs-string">'white'</span>
paragraph.style.backgroundColor = <span class="hljs-string">'green'</span>
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/12/Screenshot-2023-12-11-at-7.59.15-AM.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>The style property is used to add a background colour to the</em> <code>h1</code> element.</p>
<p>NOTE: Because this is JavaScript, you cannot use the hyphen if the CSS property name includes two or more words. For example, in CSS you would write <code>background-color</code>. But in your JavaScript code, you need to use camel case. So <code>background-color</code> becomes <code>backgroundColor</code>.</p>
<p>You can also delete a style on an element by setting the value of the property to an empty string.</p>
<pre><code class="lang-javascript">element.style.propertyName = <span class="hljs-string">""</span>
</code></pre>
<h3 id="heading-setting-styles-with-classes">Setting Styles with Classes</h3>
<p>With classes, you can create styles once and apply it to different elements. This helps make your code become more maintainable.</p>
<h4 id="heading-the-classname-property">The <code>className</code> Property</h4>
<p>The <code>className</code> property represent the class attribute of a DOM element. And you can use it to get or set the value of the class attribute.</p>
<p>Here's an example:</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">p</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"food rice-dish"</span>&gt;</span>Jollof rice<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
</code></pre>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> jollofParagraph = <span class="hljs-built_in">document</span>.querySelector(<span class="hljs-string">'p'</span>)

<span class="hljs-built_in">console</span>.log(jollofParagraph.className)

jollofParagraph.className = <span class="hljs-string">'favorite'</span>

<span class="hljs-built_in">console</span>.log(jollofParagraph.className)
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/12/Screenshot-2023-12-11-at-9.13.37-AM.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>Example of changing the value of a class with the</em> <code>className</code> property.</p>
<p>The <code>className</code> also reads or replace the current class. In the example above, the first log statement prints the original value of the class. And after updating the <code>className</code>, the second log statement prints the new value for class.</p>
<p>But there is a more flexible property. For example, what if instead of replacing the old class with the new class, you wanted to add another class? That's where the <code>classList</code> property comes in.</p>
<h4 id="heading-the-classlist-property">The <code>classList</code> Property</h4>
<p>With the <code>classList</code> property, you can add and remove classes. You can also toggle classes, replace existing class values with new ones, and even check if the class contains a specific value.</p>
<p>Here's an example:</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">p</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"food"</span>&gt;</span>Jollof rice<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
</code></pre>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> jollofParagraph = <span class="hljs-built_in">document</span>.querySelector(<span class="hljs-string">'p'</span>)
<span class="hljs-built_in">console</span>.log(jollofParagraph.classList)
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/12/Screenshot-2023-12-11-at-9.43.30-AM.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>Shows the current classList with only one value</em></p>
<h4 id="heading-adding-classes-with-classlistadd">Adding Classes with <code>classList.add()</code></h4>
<pre><code class="lang-javascript">jollofParagraph.classList.add(<span class="hljs-string">'fav'</span>, <span class="hljs-string">'tasty'</span>)

<span class="hljs-built_in">console</span>.log(jollofParagraph.classList)
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/12/Screenshot-2023-12-11-at-9.46.14-AM.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>Example of adding new classes with</em> <code>classList.add</code>.</p>
<p>The code adds two new classes <code>fav</code> and <code>tasty</code> to the class list.</p>
<h4 id="heading-removing-classes-with-classlistremove">Removing Classes With <code>classList.remove()</code></h4>
<pre><code class="lang-javascript">jollofParagraph.classList.remove(<span class="hljs-string">'tasty'</span>)

<span class="hljs-built_in">console</span>.log(jollofParagraph.classList)
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/12/Screenshot-2023-12-11-at-9.50.26-AM.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>Example of removing classes with</em> <code>classList.remove</code>.</p>
<p>The code removes the class <code>tasty</code> from the class list.</p>
<h4 id="heading-replacing-classes-with-classlistreplace">Replacing Classes with <code>classList.replace()</code></h4>
<pre><code class="lang-javascript">jollofParagraph.classList.replace(<span class="hljs-string">'fav'</span>, <span class="hljs-string">'favorite'</span>)

<span class="hljs-built_in">console</span>.log(jollofParagraph.classList)
</code></pre>
<p>The code replaces the class <code>fav</code> with <code>favorite</code></p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/12/Screenshot-2023-12-11-at-9.53.30-AM.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>Example of replacing classes with</em> <code>classList.replace</code>.</p>
<h4 id="heading-check-the-presence-of-a-class-with-classlistcontains">Check the Presence of a Class with <code>classList.contains()</code></h4>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> isFavorite = jollofParagraph.classList.contains(<span class="hljs-string">'favorite'</span>)
<span class="hljs-keyword">const</span> isSoup = jollofParagraph.classList.contains(<span class="hljs-string">'soup'</span>)

<span class="hljs-built_in">console</span>.log(<span class="hljs-string">"Contains favorite: "</span>, isFavorite)
<span class="hljs-built_in">console</span>.log(<span class="hljs-string">"Contains soup: "</span>, isSoup)
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/12/Screenshot-2023-12-11-at-10.09.53-AM.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>Example checking if a class exists with</em> <code>classList.contains</code>.</p>
<p>The code checks if the class passed to it is contained in the class list.</p>
<p>It returns <code>true</code> if it is included in the class list (for example <code>favorite</code>) and <code>false</code> if it is not included in the class list (for example <code>soup</code>)</p>
<h4 id="heading-toggling-a-class-with-the-classlisttoggle">Toggling a Class with the <code>classList.toggle()</code></h4>
<p>When you use the <code>toggle</code> property, it first checks if the class exists. If it exists, it will remove it. And if it doesn't exist, it will add it.</p>
<pre><code class="lang-javascript">jollofParagraph.classList.toggle(<span class="hljs-string">'favorite'</span>)
<span class="hljs-built_in">console</span>.log(jollofParagraph.classList)

jollofParagraph.classList.toggle(<span class="hljs-string">'favorite'</span>)
<span class="hljs-built_in">console</span>.log(jollofParagraph.classList)

jollofParagraph.classList.toggle(<span class="hljs-string">'favorite'</span>)
<span class="hljs-built_in">console</span>.log(jollofParagraph.classList)
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/12/Screenshot-2023-12-11-at-10.19.18-AM.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>Example of toggling a class value with</em> <code>classList.toggle</code>.</p>
<p>The first time the toggle runs, <code>favorite</code> exists in the class list. So, the toggle removes it.</p>
<p>The second time the toggle runs, <code>favorite</code> doesn't exist so the toggle adds <code>favorite</code> to the class list.</p>
<p>The next time the toggle runs, <code>favorite</code> now exists again. So it removes it from the class list.</p>
<p>The toggle keeps adding or removing the value from the class list depending on whether it's present or absent.</p>
<h2 id="heading-how-to-traverse-the-dom">How to Traverse the DOM</h2>
<p>To traverse the DOM means to move between the different elements/nodes within the HTML document. This may includes selecting or accessing parent, child, or sibling elements (or nodes). You do this to get information or manipulate the document structure.</p>
<p>But before we get into how to traverse the DOM, you need to understand the difference between nodes and elements.</p>
<h3 id="heading-difference-between-a-node-and-an-element">Difference Between a Node and an Element</h3>
<p>Nodes are the building blocks of the DOM. They represents different components in the HTML structure.</p>
<p>Elements are a specific type of node, but not all nodes are elements. Other types of content like attributes of elements, text content, and comments within the code are nodes too. But they are not elements.</p>
<p>An element is a specific type of node that defines the structure of the document's content. Think of elements as the familiar HTML tags you use. Examples include <code>&lt;div&gt;</code>, <code>&lt;p&gt;</code>, and <code>&lt;ul&gt;</code>. Each element can consist of attributes, text content, and other nested elements.</p>
<h3 id="heading-selecting-a-parent-with-parentnode-vs-parentelement">Selecting a Parent with <code>parentNode</code> vs <code>parentElement</code></h3>
<p>When it comes to selecting the parent of a DOM element, you can use either the <code>parentNode</code> or <code>parentElement</code>. Both will get the parent of the element you pass to it.</p>
<p>From a practical viewpoint, the parent of an element or a node will always be an element. So it doesn't matter which one you use, you will get the right parent of the selected element.</p>
<p>Let's see an example of selecting the parent of an element.</p>
<pre><code class="lang-html">  <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"container"</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">p</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"full-text"</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">i</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"italics"</span>&gt;</span>Some italicized text<span class="hljs-tag">&lt;/<span class="hljs-name">i</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
</code></pre>
<pre><code class="lang-json">const italicizedText = document.getElementById('italics')

console.log(italicizedText.parentNode)
console.log(italicizedText.parentNode.parentNode)
</code></pre>
<p>First, you select the element. Then, you chain the <code>parentNode</code> method to it to get the parent. You can also chain another <code>parentNode</code> property to get the parent of a parent element like the second log statement.</p>
<p>The screenshot below shows the output of the two log statements.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/12/Screenshot-2023-12-12-at-9.44.45-AM.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>Example of selecting the parent of an element.</em></p>
<h3 id="heading-selecting-elements-with-childnodes-vs-children">Selecting Elements with <code>childNodes</code> vs <code>children</code></h3>
<p>You can select the contents of an element using both the <code>.childNodes</code> and <code>.children</code> properties. But they work differently.</p>
<p><code>childNodes</code>: returns a NodeList of all the child nodes within the selected elements. It will include elements and non-element nodes like text nodes, comment nodes, and so on.</p>
<p><code>.children</code>: returns an HTML collection of only the child elements (element nodes) of the selected objects. It will not include any non-element nodes like texts or comments.</p>
<p>Let's see an example that shows the difference:</p>
<pre><code class="lang-html">  <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"container"</span>&gt;</span>
    A text node
    <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>Some paragraph<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
    <span class="hljs-comment">&lt;!-- This is a comment --&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">span</span>&gt;</span>Span Element<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
</code></pre>
<p>The code above has only 2 child elements (element nodes): the paragraph and the span. But there are other elements too – a text node and a comment:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> container = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">'container'</span>);

<span class="hljs-keyword">const</span> containerChildNodes = container.childNodes;
<span class="hljs-keyword">const</span> containerChildren = container.children;

<span class="hljs-built_in">console</span>.log(containerChildNodes);
<span class="hljs-built_in">console</span>.log(containerChildren);
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/12/Screenshot-2023-12-12-at-10.29.23-AM.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>An example of using the .childNodes property</em></p>
<p>The <code>childNodes</code> will return all the child nodes (both elements and non-elements). It also includes the whitespaces between elements as text nodes.</p>
<p>This can be confusing to work with. So, unless you have a good reason not to, you should stick with the <code>.children</code> property.</p>
<p>The <code>children</code> will only return the child elements (the paragraph and the span).</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/12/Screenshot-2023-12-12-at-10.34.08-AM.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>An example of using the</em> <code>.children</code> property</p>
<h3 id="heading-selecting-the-first-or-last-childelement">Selecting the First or Last Child/Element</h3>
<p>If you need to select only the first/last child or element, you can use these four properties.</p>
<ul>
<li><p><code>firstChild</code>: Selects only the first child node of the parent element.</p>
</li>
<li><p><code>lastChild</code>: Selects only the last child node of the parent element.</p>
</li>
<li><p><code>firstElementChild</code>: Selects only the first child element of the parent.</p>
</li>
<li><p><code>lastElementChild</code>: Selects only the last child element of the parent.</p>
</li>
</ul>
<p>Let's use the same example from the previous section to see how each works:</p>
<pre><code class="lang-html">  <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"container"</span>&gt;</span>
    A text node
    <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>Some paragraph<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
    <span class="hljs-comment">&lt;!-- This is a comment --&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">span</span>&gt;</span>Span Element<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
</code></pre>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> container = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">'container'</span>);

<span class="hljs-built_in">console</span>.log(<span class="hljs-string">"FIRST CHILD:"</span>, container.firstChild)
<span class="hljs-built_in">console</span>.log(<span class="hljs-string">"LAST CHILD:"</span>, container.lastChild)
<span class="hljs-built_in">console</span>.log(<span class="hljs-string">"FIRST ELEMENT: "</span>, container.firstElementChild)
<span class="hljs-built_in">console</span>.log(<span class="hljs-string">"LAST ELEMENT:"</span>, container.lastElementChild)
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/12/Screenshot-2023-12-13-at-7.43.25-AM.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>Example demo selecting first child/element and last child/element</em></p>
<p>Note how <code>firstChild</code> returns the first text node but the <code>firstElementChild</code> returns the first paragraph instead. This means it ignored the text node which comes before the paragraph.</p>
<p>And also note how the <code>lastChild</code> returns a text node – even though from the markup, it looks like there's nothing after the span. That is because the <code>lastChild</code> property considers the linebreak/whitespace between the closing tag of the span and the closing tag of the div elements as a node.</p>
<p>That's why it's generally safer to stick to <code>firstElementChild</code> and <code>lastElementChild</code>.</p>
<h3 id="heading-selecting-a-sibling-of-nodes-in-the-dom">Selecting a Sibling of Nodes in the DOM</h3>
<p>You've learned how to select a parent or a child of an element. You can also select a sibling of an element. You do that using the following properties:</p>
<ul>
<li><p><code>nextSibling</code>: Selects the next node within the same parent element.</p>
</li>
<li><p><code>nextElementSibling</code>: Selects the next element, and ignores any non-element nodes.</p>
</li>
<li><p><code>previousSibling</code>: Selects the previous node within the same parent element.</p>
</li>
<li><p><code>previousElementSibling</code>: Selects the previous element, and ignores any non-element nodes.</p>
</li>
</ul>
<p>Here's an example:</p>
<pre><code class="lang-html">  <span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">p</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"one"</span>&gt;</span>First paragraph<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
    text node
    <span class="hljs-tag">&lt;<span class="hljs-name">p</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"two"</span>&gt;</span>Second paragraph<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
    another text node
    <span class="hljs-tag">&lt;<span class="hljs-name">p</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"three"</span>&gt;</span>Third paragraph<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">p</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"four"</span>&gt;</span>Fourth paragraph<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
</code></pre>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> paragraphTwo = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">'two'</span>)

<span class="hljs-built_in">console</span>.log(<span class="hljs-string">"nextSibling: "</span>, paragraphTwo.nextSibling)
<span class="hljs-built_in">console</span>.log(<span class="hljs-string">"nextElementSibling: "</span>, paragraphTwo.nextElementSibling)
<span class="hljs-built_in">console</span>.log(<span class="hljs-string">"previousSibling: "</span>, paragraphTwo.previousSibling)
<span class="hljs-built_in">console</span>.log(<span class="hljs-string">"previousElementSibling: "</span>, paragraphTwo.previousElementSibling)
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/12/Screenshot-2023-12-13-at-7.57.18-AM.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>Examples of selecting siblings of a node.</em></p>
<p><code>nextSibling</code> and <code>previousSibling</code> select the text nodes because they consider all nodes within the parent. While <code>nextElementSibling</code> and <code>previousElementSibling</code> select only the paragraph elements because they ignore non-element nodes like text.</p>
<h2 id="heading-dom-events-and-event-listeners">DOM Events and Event Listeners</h2>
<p>DOM events are actions that take place in the browser. These events are what allows you to make websites interactive.</p>
<p>Some DOM events are user-initiated like clicking, moving the mouse, or typing on the keyboard. Others are browser-initiated like when a page finishes loading.</p>
<h3 id="heading-difference-between-event-listener-and-event-handler">Difference Between Event Listener and Event Handler</h3>
<p>An event listener is a method that lets you know when an event has taken place. It allows you to "listen" or keep an eye out for DOM events. That way, when an event happens, you can do something.</p>
<p>An event handler is a response to the event. It's a function that runs when an event occurs.</p>
<p>For example, you can attach an event listener to a button that lets you know when a user clicks that button. Then you can write an event handler (a function) that prints something on screen anytime a click event occurs.</p>
<p>In this case, the event listener is what informs your app when a click occurs and then trigger a response. And the response (the function that runs when the click occurs) is an example of an event handler.</p>
<h3 id="heading-three-ways-to-register-events-in-javascript">Three Ways to Register Events in JavaScript</h3>
<p>The following are three different ways you can listen to and respond to DOM events using JavaScript.</p>
<ul>
<li><strong>Using inline event handlers:</strong> This is when you add the event listener as an attribute to HTML elements. In the early days of JavaScript, this was the only way to use events. See the example below:</li>
</ul>
<pre><code class="lang-javascript"><span class="hljs-comment">// Example of using an inline event handler</span>

&lt;button onclick=<span class="hljs-string">"alert('Hello')"</span>&gt;Click me!&lt;/button&gt;
</code></pre>
<ul>
<li><strong>Using on-event handlers:</strong> You use this when an element has only one event handler. When you add more than one event handler using this method, only the last event handler will run, as it will override others before it.</li>
</ul>
<pre><code class="lang-html"><span class="hljs-comment">&lt;!-- An example of using an on-event handler --&gt;</span>

<span class="hljs-tag">&lt;<span class="hljs-name">button</span>&gt;</span>Click me!<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>

<span class="hljs-tag">&lt;<span class="hljs-name">script</span>&gt;</span><span class="javascript">
  <span class="hljs-keyword">const</span> myButton = <span class="hljs-built_in">document</span>.querySelector(<span class="hljs-string">'button'</span>)

  myButton.onclick = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) </span>{
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"Run first handler"</span>)
  }

  myButton.onclick = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) </span>{
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"Run second handler"</span>)
  }
</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/12/Screenshot-2023-12-14-at-7.41.49-AM.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>Only the second event handler is executed.</em></p>
<p>As you can see from the result in the console, the browser runs the code for only the second event handler.</p>
<ul>
<li><strong>Using the</strong> <code>addEventListener</code> method: This method allows you to attach more than one event handlers to an element. And it will execute them in the order in which they were added.</li>
</ul>
<p>As a general rule, you should stick with the <code>addEventListener</code>, unless you have a compelling reason not to.</p>
<p>The <code>addEventListener</code> method takes two arguments. The first is the event you want to listen to, and the second is the event handler which is the function you want to run when the event occurs.</p>
<pre><code class="lang-html"><span class="hljs-comment">&lt;!-- An example of using the addEventListener method --&gt;</span>

<span class="hljs-tag">&lt;<span class="hljs-name">button</span>&gt;</span>Click me!<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>

<span class="hljs-tag">&lt;<span class="hljs-name">script</span>&gt;</span><span class="javascript">
  <span class="hljs-keyword">const</span> myButton = <span class="hljs-built_in">document</span>.querySelector(<span class="hljs-string">'button'</span>)

  myButton.addEventListener(<span class="hljs-string">'click'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) </span>{
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"Run first handler"</span>)
  })

  myButton.addEventListener(<span class="hljs-string">'click'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) </span>{
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"Run second handler"</span>)
  })
</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/12/Screenshot-2023-12-14-at-7.51.22-AM.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>The</em> <code>addEventListener</code> method executes both event handlers.</p>
<h3 id="heading-practice-challenge">Practice Challenge</h3>
<p>Here is a challenge for you before you move on. Try solving it on your own before you take a look at the solution.</p>
<p>Consider the HTML and CSS code below.</p>
<p>The challenge includes two elements. A <code>#gift-box</code> div and a <code>#click-btn</code> button. The gift box is hidden with the <code>.hide</code> class.</p>
<p>Your task is write JavaScript code that listens to a click event on the button, and display the hidden box when the user clicks the button.</p>
<pre><code class="lang-html"><span class="hljs-meta">&lt;!DOCTYPE <span class="hljs-meta-keyword">html</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">html</span> <span class="hljs-attr">lang</span>=<span class="hljs-string">"en"</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">head</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">head</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">body</span>&gt;</span>

      <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"gift-box"</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"hide"</span>&gt;</span>🎁<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"click-btn"</span>&gt;</span>Show the box<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>

  <span class="hljs-tag">&lt;/<span class="hljs-name">body</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">html</span>&gt;</span>
</code></pre>
<pre><code class="lang-css"><span class="hljs-selector-class">.hide</span> {
  <span class="hljs-attribute">display</span>: none;
}

<span class="hljs-selector-id">#gift-box</span> {
  <span class="hljs-attribute">font-size</span>: <span class="hljs-number">5em</span>;
}
</code></pre>
<p>&lt;a href="https://stackblitz.com/edit/js-cywa91?file=index.html,style.css,index.js" target="_blank"</p>
<p><strong>Solve the challenge on StackBlitz</strong>  </p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/12/ezgif.com-video-to-gif-converted.gif" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>Demo gif for the final solution of the challenge</em></p>
<h3 id="heading-solution-to-practice-challenge">Solution to Practice Challenge</h3>
<p>Congratulations if you were able to solve the challenge. If you were not, that's okay. The solution and explanation is provided below:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> giftBoxElement = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">'gift-box'</span>)
<span class="hljs-keyword">const</span> buttonElement = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">'click-btn'</span>)

buttonElement.addEventListener(<span class="hljs-string">'click'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) </span>{
  giftBoxElement.classList.remove(<span class="hljs-string">'hide'</span>)
})
</code></pre>
<p>To solve this challenge, first you need to select both the <code>#gift-box</code> and <code>#click-btn</code> element.</p>
<p>Then, you add an event listener to the button. As mentioned earlier, the <code>addEventListener</code> method takes in two arguments.</p>
<p>In this case, the first argument is the 'click' event, and the second argument is a function.</p>
<p>The goal is to display the box. The box has a class <code>hide</code> which sets <code>display</code> to <code>none</code> in the CSS. One way to display the box using JavaScript is to remove <code>hide</code> from the classList.</p>
<h3 id="heading-the-event-object">The Event Object</h3>
<p>This is a JavaScript object the browser passes as an argument to the event handler function anytime an event occurs. The object includes some useful properties and methods like the following:</p>
<ul>
<li><p><code>type</code>: the type of event that occurred (like click, mouseover, keydown, and so on)</p>
</li>
<li><p><code>target</code>: the element on which the event occurred</p>
</li>
<li><p><code>clientX</code> and <code>clientY</code>: the horizontal and vertical coordinates of the mouse pointer at the time the event occurred.</p>
</li>
<li><p><code>preventDefault()</code>: prevents default actions associated with the events like preventing a form submission on the submit event.</p>
</li>
<li><p><code>stopPropagation()</code>: prevents the event from propagating through the DOM. More on that later.</p>
</li>
</ul>
<p>You can see a full list of the properties and methods on <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/API/Event">the MDN web docs</a>.</p>
<h3 id="heading-types-of-events">Types of Events</h3>
<p>There are many different kinds of DOM events the browsers lets you listen to. The following are few of the common ones.</p>
<p><strong>Mouse events:</strong></p>
<ul>
<li><p><code>click</code>: when the element is clicked.</p>
</li>
<li><p><code>dbclick</code>: when the element is double clicked.</p>
</li>
<li><p><code>mouseover</code>: when the mouse pointer enters the element.</p>
</li>
<li><p><code>mouseleave</code>: when the mouse pointer leaves the element.</p>
</li>
<li><p><code>mousedown</code>: when the mouse is pressed down over an element.</p>
</li>
<li><p><code>mouseup</code>: when the mouse is released over an element.</p>
</li>
</ul>
<p><strong>Keyboard events:</strong></p>
<ul>
<li><p><code>keydown</code>: when a key on the keyboard is pressed down.</p>
</li>
<li><p><code>keyup</code>: when a key on the keyboard is released.</p>
</li>
<li><p><code>keypress</code>: when a key is pressed and shows the actual key that was pressed. Note that this event is not fired for all keys, especially non-printable keys.</p>
</li>
</ul>
<p><strong>Form events:</strong></p>
<ul>
<li><p><code>submit</code>: when a form is submitted.</p>
</li>
<li><p><code>input</code>: when the value of an input field changes.</p>
</li>
<li><p><code>change</code>: when the value of a form element changes and loses focus.</p>
</li>
</ul>
<p><strong>Window events:</strong></p>
<ul>
<li><p><code>load</code>: when the browser finishes loading the page.</p>
</li>
<li><p><code>unload</code>: when the user leaves the page.</p>
</li>
<li><p><code>resize</code>: when the browser window is resized.</p>
</li>
<li><p><code>scroll</code>: when the user scrolls through the document.</p>
</li>
</ul>
<p>You can see <a target="_blank" href="https://www.w3schools.com/jsref/dom_obj_event.asp">a comprehensive list of DOM events here</a>.</p>
<h2 id="heading-event-flow-in-javascript">Event Flow in JavaScript</h2>
<p>When a JavaScript event occurs, the event is propagated or travels either from the target where the event occurred to the outermost element in the DOM or vice versa.</p>
<p>For example, let's say you click a button on a page. By clicking the button, you've also clicked its parent element and any element the button is inside within the DOM hierarchy.</p>
<h3 id="heading-event-bubbling">Event Bubbling</h3>
<p>This is when the event is first registered on the target (or specified element) on which the event happened, and then registered outwards to the parent and onwards to the outermost element.</p>
<p>Here's an example:</p>
<pre><code class="lang-html"><span class="hljs-meta">&lt;!DOCTYPE <span class="hljs-meta-keyword">html</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">html</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">head</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">title</span>&gt;</span>Event bubbling DEMO<span class="hljs-tag">&lt;/<span class="hljs-name">title</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">head</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">body</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"outer"</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"inner"</span>&gt;</span>
              <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">id</span>=<span class="hljs-string">'btn'</span>&gt;</span>Click Here<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
            <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">body</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">html</span>&gt;</span>
</code></pre>
<p>The example here contains a button <code>#btn</code>. With event bubbling, when an event occurs (say a click) on the button, the event goes through the following sequence.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/12/4.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>Event bubbling in DOM Manipulation: from button to div#inner to div#outer to body to HTML to document.</em></p>
<p>The event starts to bubble up from the target element back to the outermost ancestor.</p>
<h3 id="heading-event-capturing">Event Capturing</h3>
<p>Event capturing is the opposite of event bubbling. The event starts from the outermost ancestor element and travels down the DOM tree to the target element.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/12/JavaScript--2-.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>Event capturing in DOM Manipulation</em></p>
<p>During the capturing phase, event listeners attached to elements are executed in the order of the hierarchy from the topmost ancestor to the target element.</p>
<p>In case you're wondering why this matters, let's see a practical example using the same HTML markup example from above:</p>
<pre><code class="lang-html"><span class="hljs-meta">&lt;!DOCTYPE <span class="hljs-meta-keyword">html</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">html</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">head</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">title</span>&gt;</span>Event bubbling DEMO<span class="hljs-tag">&lt;/<span class="hljs-name">title</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">head</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">body</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"outer"</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"inner"</span>&gt;</span>
              <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">id</span>=<span class="hljs-string">'btn'</span>&gt;</span>Click Here<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
            <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">body</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">html</span>&gt;</span>
</code></pre>
<p>Let's add event listeners to the button, the <code>#inner</code> div, and the <code>#outer</code> div:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> button = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">'btn'</span>)
<span class="hljs-keyword">const</span> innerDiv = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">'inner'</span>)
<span class="hljs-keyword">const</span> outerDiv = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">'outer'</span>)

button.addEventListener(<span class="hljs-string">'click'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'Click on button'</span>)
})

innerDiv.addEventListener(<span class="hljs-string">'click'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'Click on inner Div'</span>)
})

outerDiv.addEventListener(<span class="hljs-string">'click'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'Click on outer Div'</span>)
})
</code></pre>
<p>By default, browsers use the event bubbling approach. So there is no need to add any argument to the event listener. This is the order in which the event handlers will run in response to a click on the button:</p>
<ol>
<li><p><code>button</code></p>
</li>
<li><p><code>#innerDiv</code></p>
</li>
<li><p><code>#outerDiv</code></p>
</li>
</ol>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/12/Screenshot-2023-12-15-at-11.54.07-AM.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>Events are executed from the element to the outermost element in the bubbling phase.</em></p>
<p>To use the event capturing model, you need to pass a third argument <code>true</code> to the event listener.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> button = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">'btn'</span>)
<span class="hljs-keyword">const</span> innerDiv = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">'inner'</span>)
<span class="hljs-keyword">const</span> outerDiv = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">'outer'</span>)

button.addEventListener(<span class="hljs-string">'click'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'Click on button'</span>)
}, <span class="hljs-literal">true</span>)

innerDiv.addEventListener(<span class="hljs-string">'click'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'Click on inner Div'</span>)
}, <span class="hljs-literal">true</span>)

outerDiv.addEventListener(<span class="hljs-string">'click'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'Click on outer Div'</span>)
}, <span class="hljs-literal">true</span>)
</code></pre>
<p>The order for executing the event handlers will now run in the opposite direction, like this:</p>
<ol>
<li><p><code>#outerDiv</code></p>
</li>
<li><p><code>#innerDiv</code></p>
</li>
<li><p><code>button</code></p>
</li>
</ol>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/12/Screenshot-2023-12-15-at-11.58.38-AM.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>Events are executed from the outermost element to the element in the capturing phase.</em></p>
<h3 id="heading-the-event-stoppropagation-method">The Event <code>stopPropagation()</code> Method</h3>
<p>You've learned about how the event bubbling registers an event on an element and continues registering the event all the way to the outermost ancestor element. You've also seen how event capturing does the opposite.</p>
<p>But what if you don't want the event to register on all the ancestors? That's where the <code>stopPropagation</code> method comes in. You can use this method to prevent the event from propagating through the whole DOM.</p>
<p>Let's use the <code>stopPropagation</code> method on the same example from before:</p>
<pre><code class="lang-javascript">button.addEventListener(<span class="hljs-string">'click'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">event</span>) </span>{
  event.stopPropagation()
  <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'Click on button'</span>)
})

innerDiv.addEventListener(<span class="hljs-string">'click'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'Click on inner Div'</span>)
})

outerDiv.addEventListener(<span class="hljs-string">'click'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'Click on outer Div'</span>)
})
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/12/Screenshot-2023-12-15-at-2.48.37-PM.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>The</em> <code>stopPropagation</code> method allows the execution of only the first event listener.</p>
<p>Now, only the event handler on the button is fired. The ones on the <code>innerDiv</code> and <code>outerDiv</code> are not because of the <code>stopPropagation</code> method on the button.</p>
<p>Also, note that to get the event object, you need to pass it as an argument to the event handler function.</p>
<h2 id="heading-js-dom-manipulation-project-ideas">JS DOM Manipulation Project Ideas</h2>
<p>Building projects is an excellent way to improve your understanding of coding concepts. So roll up your sleeves and get ready to work!</p>
<p>Here are five JS DOM manipulation project ideas to help you practice and solidify your skills.</p>
<h3 id="heading-toggle-switch">Toggle Switch</h3>
<p>Design a toggle switch that changes its state (on/off) when clicked. Update the DOM (for example with a background color) that reflects the current state of the toggle switch.</p>
<h3 id="heading-random-color-picker">Random Color Picker</h3>
<p>Create a simple app where users can click a button to generate a random color. Include a shape on the screen that gets filled with the chosen color. Also display the color code on screen.</p>
<h3 id="heading-countdown-timer">Countdown Timer</h3>
<p>Build a timer that starts from a specified time. The app updates in real time and shows the remaining time on the screen.</p>
<h3 id="heading-word-counter">Word Counter</h3>
<p>Develop an app that provides an input field or text area for the user to type. Display the number of words in real time on the screen as the user types.</p>
<h3 id="heading-an-interactive-to-do-list">An Interactive To-Do List</h3>
<p>Create an app that allows users to add, delete, or edit tasks. You can have fun with this one and add as many advanced features as you want. For example, adding features like marking tasks as completed, filtering tasks, or sorting them.</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>If you've come this far, then you now have a good understanding of JavaScript DOM manipulation. With practice, you'll be confident enough to tackle advanced projects that require knowledge of these DOM manipulation concepts.</p>
<p>A good foundation of Vanilla JS DOM manipulation concepts will also come in handy when picking JavaScript libraries/frameworks like React, Angular, Vue, Svelte, and so on.</p>
<p>Thank you for reading, and happy coding! For more in-depth tutorials, feel free to <a target="_blank" href="https://www.youtube.com/@DevAfterHours">subscribe to my YouTube channel</a>.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ innerHTML vs innerText vs textContent – What's the Difference? ]]>
                </title>
                <description>
                    <![CDATA[ By Benjamin Semah In HTML, innerHTML, innerText, and textContent are properties of the DOM (Document Object Model). They allow you to read and update the content of HTML elements. But they have different behaviours in terms of the content they includ... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/innerhtml-vs-innertext-vs-textcontent/</link>
                <guid isPermaLink="false">66d45ddfc7632f8bfbf1e3fb</guid>
                
                    <category>
                        <![CDATA[ DOM ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Front-end Development ]]>
                    </category>
                
                    <category>
                        <![CDATA[ HTML ]]>
                    </category>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Web Development ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Mon, 11 Dec 2023 21:57:38 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2023/12/Benjamin-Semah---DevAfterHours-1.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Benjamin Semah</p>
<p>In HTML, <code>innerHTML</code>, <code>innerText</code>, and <code>textContent</code> are properties of the DOM (Document Object Model). They allow you to read and update the content of HTML elements.</p>
<p>But they have different behaviours in terms of the content they include and how they handle HTML markup.</p>
<p>By the end of this article, you will know the differences between these three properties and when you should each one. </p>
<h2 id="heading-table-of-contents">Table of Contents</h2>
<ul>
<li><a class="post-section-overview" href="#heading-what-is-the-innerhtml-property">What is the <code>innerHTML</code> property?</a></li>
<li><a class="post-section-overview" href="#heading-what-is-the-innertext-property">What is the <code>innerText</code> property?</a></li>
<li><a class="post-section-overview" href="#heading-what-is-the-textcontent-property">What is thet <code>textContent</code> property?</a></li>
<li><a class="post-section-overview" href="#heading-how-to-read-content-with-innerhtml-innertext-and-textcontent">How to read content with <code>innerHTML</code>, <code>innerText</code>, and <code>textContent</code></a></li>
<li><a class="post-section-overview" href="#heading-how-to-update-content-with-innerhtml-innertext-and-textcontent">How to update content with <code>innerHTML</code>, <code>innerText</code>, and <code>textConent</code></a></li>
<li><a class="post-section-overview" href="#heading-security-concerns-when-using-innerhtml">Security concerns when using <code>innerHTML</code></a></li>
<li><a class="post-section-overview" href="#heading-conclusion">Conclusion</a></li>
</ul>
<p>First, I'll explain how these three properties work. And then you will see some example use cases to learn the differences in their behaviour.</p>
<h2 id="heading-what-is-the-innerhtml-property">What is the <code>innerHTML</code> Property?</h2>
<p>When you use the <code>innerHTML</code> property, it reads both the HTML markup and the text content of the element. This means when you use it to set the content of elements, you can include HTML tags, and the browser will render them correctly.</p>
<p>But, be cautious if you're inserting content from user input or any untrusted source with <code>innerHTML</code>. Attackers can use the HTML <code>&lt;script&gt;</code> tag to insert and run malicious code in your app. More on that later in the article.</p>
<h2 id="heading-what-is-the-innertext-property">What is the <code>innerText</code> Property?</h2>
<p>This property focuses on the rendered text content. When you use <code>innerText</code> to read the content of an element, it returns the text as it appears on screen. It ignores HTML tags. And it also does not include text that is hidden with CSS styles. </p>
<p>When you need to account for styles, you should consider using <code>innerText</code>. Modifying the <code>innerText</code> of an element means the browser may need to adjust the layout to accommodate the changes in text size, which can have performance implications.</p>
<h2 id="heading-what-is-the-textcontent-property">What is the <code>textContent</code> Property?</h2>
<p>The <code>textContent</code> property also ignores all HTML tags and returns only the text. Whiles <code>innerText</code> reads text as it is rendered on screen, <code>textContent</code> reads text as it is in the markup. It also returns all text, whether it's rendered on screen or not.</p>
<p>Also, <code>textContent</code> only deals with the raw text and doesn't account for styles. So, in situations where performance is a concern and you don't need to account for styles, <code>textContent</code> might be a more efficient choice compared to <code>innerText</code>.</p>
<h2 id="heading-how-to-read-content-with-innerhtml-innertext-and-textcontent">How to Read Content with <code>innerHTML</code>, <code>innerText</code>, and <code>textContent</code></h2>
<p>Now, let's see some practical examples to understand the three properties better.</p>
<p>The following is a simple markup for a navigation bar with four items. The last element with the text "Pricing" is hidden (display set to none). Let's read the content of the <code>nav</code> element using all three properties to see the difference.</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">nav</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">a</span>&gt;</span>Home<span class="hljs-tag">&lt;/<span class="hljs-name">a</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">a</span>&gt;</span>About<span class="hljs-tag">&lt;/<span class="hljs-name">a</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">a</span>&gt;</span>Contact<span class="hljs-tag">&lt;/<span class="hljs-name">a</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">a</span> <span class="hljs-attr">style</span>=<span class="hljs-string">"display: none"</span>&gt;</span>Pricing<span class="hljs-tag">&lt;/<span class="hljs-name">a</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">nav</span>&gt;</span>
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/12/Screenshot-2023-12-07-at-11.37.48-AM.png" alt="Image" width="600" height="400" loading="lazy">
<em>A simple nav bar example</em></p>
<h3 id="heading-getting-content-with-innerhtml">Getting content with <code>innerHTML</code></h3>
<pre><code class="lang-javascript"><span class="hljs-comment">// Reading content with innerHTML</span>
<span class="hljs-keyword">const</span> navElement = <span class="hljs-built_in">document</span>.querySelector(<span class="hljs-string">'nav'</span>)
<span class="hljs-built_in">console</span>.log(navElement.innerHTML)
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/12/Screenshot-2023-12-07-at-11.32.01-AM.png" alt="innerHTML example that includes both markup and text" width="600" height="400" loading="lazy">
<em>innerHTML example that includes both markup and text</em></p>
<p>The <code>innerHTML</code> property returns the full content including all the HTML tags inside the <code>nav</code> elements and their text content.</p>
<h3 id="heading-getting-content-with-innertext">Getting content with <code>innerText</code></h3>
<pre><code class="lang-javascript"><span class="hljs-comment">// Reading content with innerText</span>
<span class="hljs-keyword">const</span> navElement = <span class="hljs-built_in">document</span>.querySelector(<span class="hljs-string">'nav'</span>)
<span class="hljs-built_in">console</span>.log(navElement.innerText)
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/12/Screenshot-2023-12-07-at-11.36.52-AM.png" alt="Image" width="600" height="400" loading="lazy">
<em>innerText example that prints text as it appears on screen</em></p>
<p>The <code>innerText</code> property returns the content as rendered on the screen. It ignores all the HTML tags. And it also ignores the hidden element (with display set to none).</p>
<h3 id="heading-getting-content-with-textcontent">Getting content with <code>textContent</code></h3>
<pre><code class="lang-javascript"><span class="hljs-comment">// Reading content with textContent</span>
<span class="hljs-keyword">const</span> navElement = <span class="hljs-built_in">document</span>.querySelector(<span class="hljs-string">'nav'</span>)
<span class="hljs-built_in">console</span>.log(navElement.textContent)
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/12/Screenshot-2023-12-07-at-11.47.30-AM.png" alt="Image" width="600" height="400" loading="lazy">
<em>textContent example that prints text as it is in the markup including hidden text</em></p>
<p>The <code>textContent</code> property returns the content as it in the HTML markup. Like <code>innerText</code>, it also ignores the HTML tags. But it doesn't consider styles, so it returns the "Pricing" text even though it's hidden.</p>
<h2 id="heading-how-to-update-content-with-innerhtml-innertext-and-textcontent">How to Update Content with <code>innerHTML</code>, <code>innerText</code>, and <code>textContent</code></h2>
<p>You can also use all three properties to update the content of DOM elements. When updating content, the properties behave in a similar way to when you use them to read or get content.</p>
<p>Let's see some examples to understand it better</p>
<h3 id="heading-setting-content-with-innerhtml">Setting content with <code>innerHTML</code></h3>
<p>The markup below includes a header element and an empty <code>&lt;ul&gt;</code> element. You can use the <code>innerHTML</code> property to insert some content to the <code>&lt;ul&gt;</code>.</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">h2</span>&gt;</span>Programming languages<span class="hljs-tag">&lt;/<span class="hljs-name">h2</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">ul</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"languages-list"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">ul</span>&gt;</span>
</code></pre>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> langListElement = <span class="hljs-built_in">document</span>.querySelector(<span class="hljs-string">'.languages-list'</span>)

<span class="hljs-comment">// Setting or updating content with innerHTML</span>
langListElement.innerHTML = <span class="hljs-string">`
  &lt;li&gt;JavaScript&lt;/li&gt;
  &lt;li&gt;Python&lt;/li&gt;
  &lt;li&gt;PHP&lt;/li&gt;
  &lt;li&gt;Ruby&lt;/li&gt;
`</span>
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/12/Screenshot-2023-12-08-at-9.50.06-AM.png" alt="Image" width="600" height="400" loading="lazy">
<em>An example of setting content with the innerHTML property</em></p>
<p>The JavaScript code passes a string of an HTML list as the value for <code>innerHTML</code>. The <code>innerHTML</code> property recognizes the HTML tags and formats the content accordingly.</p>
<p>Unlike <code>innerHTML</code>, both <code>innerText</code> and <code>textContent</code> will ignore the HTML tags and render everything as a string.</p>
<h3 id="heading-setting-content-with-innertext">Setting content with <code>innerText</code></h3>
<p>Using the same example, let's see how the <code>innerText</code> property will update the content of the programming languages list.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> langListElement = <span class="hljs-built_in">document</span>.querySelector(<span class="hljs-string">'.languages-list'</span>)

langListElement.innerText = <span class="hljs-string">`
  &lt;li&gt;JavaScript&lt;/li&gt;
  &lt;li&gt;Python&lt;/li&gt;
  &lt;li&gt;PHP&lt;/li&gt;
  &lt;li&gt;Ruby&lt;/li&gt;
`</span>
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/12/Screenshot-2023-12-08-at-11.12.15-AM.png" alt="Image" width="600" height="400" loading="lazy">
<em>An example of setting content with the innerText property</em></p>
<p>Note how <code>innerText</code> ignores the HTML tags and prints them on screen as part of the text. But it still recognises formatting like line-breaks and whitespaces.</p>
<h3 id="heading-setting-content-with-textcontent">Setting content with <code>textContent</code></h3>
<p>When setting or updating content, the <code>textContent</code> property will ignore HTML markup and it will also ignore things like line breaks and whitespaces too.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> langListElement = <span class="hljs-built_in">document</span>.querySelector(<span class="hljs-string">'.languages-list'</span>)

langListElement.textContent = <span class="hljs-string">`
  &lt;li&gt;JavaScript&lt;/li&gt;
  &lt;li&gt;Python&lt;/li&gt;
  &lt;li&gt;PHP&lt;/li&gt;
  &lt;li&gt;Ruby&lt;/li&gt;
`</span>
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/12/Screenshot-2023-12-08-at-11.22.45-AM-1.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Because <code>textContent</code> ignores formatting like line breaks and whitespaces, all the text is printed on the same line. When you want the raw text and aren't concerned with formatting of the text, <code>textContent</code> is a suitable choice.</p>
<h2 id="heading-security-concerns-when-using-innerhtml">Security Concerns When Using <code>innerHTML</code></h2>
<p>Because <code>innerHTML</code> processes and interprets HTML tags, it is advisable to use it only when inserting content from trusted sources. Or when you have properly sanitised and validated the provided content.</p>
<p>The browser will run any JavaScript code you put in the HTML script tag. And it can open doors to <a target="_blank" href="https://www.freecodecamp.org/news/cross-site-scripting-what-is-xss/">Cross-Site Scripting (XSS)</a> where attackers can inject and run malicious script in the context of your web page.</p>
<p>See an example:</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"commentSection"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
</code></pre>
<p>Assume you are using the <code>div</code> above as container for user comments in your app. And you use <code>innerHTML</code> to add new comments without any validation or sanitizing the comment.</p>
<p>Here is a very basic example of how a user can inject and run a malicious script:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> commentSection = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">'commentSection'</span>)

<span class="hljs-keyword">let</span> userComment = <span class="hljs-string">`&lt;img src="malicious-script.jpg" onerror="alert('Malicious Script Executed!')"&gt; This is my comment!`</span>;

commentSection.innerHTML = userComment;
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/12/Screenshot-2023-12-08-at-10.35.53-AM.png" alt="Image" width="600" height="400" loading="lazy">
<em>Malicious script executed via the &lt;script&gt; tag with innerHTML</em></p>
<p>The user deliberately gives an incorrect value for the <code>src</code> attribute of the image. This will trigger the <code>onerror</code> event which runs an alert with the string "Malicious Script Executed!". </p>
<p>You can imagine how an attacker can take advantage of this to inject harmful JavaScript code, potentially stealing sensitive user information, manipulating the page content, or performing other malicious actions.</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>You can use the three properties <code>innerHTML</code>, <code>innerText</code>, and <code>textContent</code> to manipulate the content of DOM elements. But they behave differently. Understanding them will help you decide when it's appropriate to use each one. </p>
<p>The <code>innerHTML</code> property recognizes HTML tags and renders the content according to the tags. <code>innerText</code> and <code>textContent</code> ignore HTML tags and treat them as part of the text. You also learned in this article how <code>innerHTML</code> can lead to security risks and why you should be mindful of this.</p>
<p>Also, <code>innerText</code> reads content as it appears on screen, ignores hidden content, and observes formatting of text. But <code>textContent</code> reads content as it appears in the markup. This means it reads hidden content too. But it also ignores formatting like whitespaces and line breaks when you are using it set content.</p>
<p>Thanks for reading. And happy coding. For more in-depth tutorials, feel free to <a target="_blank" href="https://www.youtube.com/@DevAfterHours">subscribe to my YouTube channel</a>.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Manipulate the DOM in JavaScript – Most Commonly Used Techniques ]]>
                </title>
                <description>
                    <![CDATA[ Hi everyone! In this article, I’m going to cover everything you need to know about manipulating the DOM. Basically, each Element object in the DOM has properties and methods that you can use to interact with that element. The following are the most c... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/javascript-document-object-model-explained/</link>
                <guid isPermaLink="false">66bd9178621c718d60a3106d</guid>
                
                    <category>
                        <![CDATA[ Document Object Model ]]>
                    </category>
                
                    <category>
                        <![CDATA[ DOM ]]>
                    </category>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Nathan Sebhastian ]]>
                </dc:creator>
                <pubDate>Thu, 07 Dec 2023 22:19:23 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2023/12/js-dom-manipulation-1.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Hi everyone! In this article, I’m going to cover everything you need to know about manipulating the DOM.</p>
<p>Basically, each <code>Element</code> object in the DOM has properties and methods that you can use to interact with that element.</p>
<p>The following are the most common and practical ways you might want to manipulate the <code>Element</code> object:</p>
<ol>
<li><a class="post-section-overview" href="#heading-change-the-content-of-an-element">Change the Content of an Element</a></li>
<li><a class="post-section-overview" href="#heading-manipulate-the-class-attribute">Manipulate the Class Attribute</a></li>
<li><a class="post-section-overview" href="#heading-setting-css-styles-using-javascript">Setting CSS Styles Using JavaScript</a></li>
<li><a class="post-section-overview" href="#heading-create-add-and-remove-elements">Create, Add, and Remove Elements</a></li>
<li><a class="post-section-overview" href="#heading-insert-element-at-a-specific-position">Insert Element at a Specific Position</a></li>
<li><a class="post-section-overview" href="#heading-manipulating-element-attributes">Manipulating Element Attributes</a></li>
<li><a class="post-section-overview" href="#heading-manipulating-data-attributes">Manipulating Data Attributes</a></li>
</ol>
<p>Manipulating the DOM seems complex in theory, but as you’ll see in this article, there are a few methods that you’ll use over and over again in many scenarios.</p>
<p>Once you know about these methods, you will have leveled up your skill in DOM manipulation. Let’s begin!</p>
<h2 id="heading-change-the-content-of-an-element">Change the Content of an Element</h2>
<p>You can change the value or content of an element by setting the <code>innerText</code> property of that element.</p>
<p>For example, suppose you have a paragraph element as follows:</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">p</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"myParagraph"</span>&gt;</span>This is a paragraph<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
</code></pre>
<p>Next, you select the element and change its <code>innerText</code> value like this:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> p = <span class="hljs-built_in">document</span>.querySelector(<span class="hljs-string">'.myParagraph'</span>);

p.innerText = <span class="hljs-string">'A new day is dawning'</span>;
</code></pre>
<p>The <code>p</code> element would have its value changed as you see below:</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">p</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"myParagraph"</span>&gt;</span>A new day is dawning<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
</code></pre>
<p>And that’s how you change the value of an element.</p>
<h2 id="heading-manipulate-the-class-attribute">Manipulate the Class Attribute</h2>
<p>You can add a new <code>class</code> attribute to an <code>Element</code> by using the <code>add()</code> method of the <code>classList</code> object:</p>
<pre><code class="lang-js">Element.classList.add(<span class="hljs-string">'myClass'</span>);
</code></pre>
<p>You can remove a class using the <code>remove()</code> method:</p>
<pre><code class="lang-js">Element.classList.remove(<span class="hljs-string">'myClass'</span>);
</code></pre>
<p>The <code>classList</code> object is a collection object that you can use to manipulate the <code>class</code> attribute of an <code>Element</code>.</p>
<p>You can’t directly edit the <code>classList</code> property because it’s a read-only property. But you can use its methods to change the element classes.</p>
<p>To replace an existing class with a new class, use the <code>replace()</code> method:</p>
<pre><code class="lang-js">Element.classList.replace(<span class="hljs-string">'oldClass'</span>, <span class="hljs-string">'newClass'</span>);
</code></pre>
<p>There’s also the <code>toggle()</code> method, which works like a switch: adds a class if it’s not there, removes a class if it’s there.</p>
<pre><code class="lang-js">Element.classList.toggle(<span class="hljs-string">'myClass'</span>);
</code></pre>
<p>To check if an element contains a specific class, use the <code>contains()</code> method and pass the class you want to check as a string:</p>
<pre><code class="lang-js">Element.classList.contains(<span class="hljs-string">'myClass'</span>);
</code></pre>
<p>The method returns <code>true</code> when the class is specified. Otherwise it returns <code>false</code>.</p>
<h2 id="heading-setting-css-styles-using-javascript">Setting CSS Styles Using JavaScript</h2>
<p>Since you’ve learned how to set and remove classes from an element, you can control the style of an element by adding or removing classes that change the style rules applied to an element.</p>
<p>For example, you might have the following style rules in your CSS code:</p>
<pre><code class="lang-css"><span class="hljs-selector-class">.color-primary</span> {
  <span class="hljs-attribute">color</span>: <span class="hljs-number">#007bff</span>;
}

<span class="hljs-selector-class">.color-secondary</span> {
  <span class="hljs-attribute">color</span>: <span class="hljs-number">#6c757d</span>;
}

<span class="hljs-selector-class">.bold</span> {
  <span class="hljs-attribute">font-weight</span>: <span class="hljs-number">700</span>;
}
</code></pre>
<p>If you have an element with the <code>color-primary</code> class applied, you can replace it with <code>color-secondary</code> class, or add the <code>bold</code> class. </p>
<p>Suppose you have a paragraph element as follows:</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">p</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"myParagraph"</span>&gt;</span>A new day is dawning<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
</code></pre>
<p>Here’s how you change the style using classes:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> p = <span class="hljs-built_in">document</span>.querySelector(<span class="hljs-string">'.myParagraph'</span>);

<span class="hljs-comment">// add a class to the element</span>
p.classList.add(<span class="hljs-string">'color-primary'</span>);

<span class="hljs-comment">// replace a class</span>
p.classList.replace(<span class="hljs-string">'color-primary'</span>, <span class="hljs-string">'color-secondary'</span>);

<span class="hljs-comment">// remove a class</span>
p.classList.remove(<span class="hljs-string">'color-secondary'</span>);
</code></pre>
<p>At times, you might need to apply CSS directly to the DOM element you selected.</p>
<p>The <code>Element</code> object provides you with the <code>style</code> property which controls the inline style of the element.</p>
<p>For example, you can change the font weight of an element using the <code>Element.style.fontWeight</code> property like this:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> p = <span class="hljs-built_in">document</span>.querySelector(<span class="hljs-string">'.myParagraph'</span>);

p.style.fontWeight = <span class="hljs-string">'700'</span>; <span class="hljs-comment">// set font weight</span>
p.style.textTransform = <span class="hljs-string">'uppercase'</span>; <span class="hljs-comment">// set to uppercase</span>
p.style.color = <span class="hljs-string">'#007bff'</span>; <span class="hljs-comment">// set color</span>
</code></pre>
<p>You can change the border style of an element as follows:</p>
<pre><code class="lang-js">p.style.border = <span class="hljs-string">'1px solid black'</span>;
</code></pre>
<p>The <code>style</code> property uses the camelCase instead of the hyphen-case, so <code>font-weight</code> becomes <code>fontWeight</code> and <code>text-transform</code> becomes <code>textTransform</code>.</p>
<p>And now you know how to set CSS styles using JavaScript. I would recommend that you change element styles by adding and removing classes because it’s more maintainable and follows the common approach.</p>
<p>Only access the <code>style</code> property if you won’t use the same style anywhere else.</p>
<h2 id="heading-create-add-and-remove-elements">Create, Add, and Remove Elements</h2>
<p>Besides creating a DOM tree out of your HTML file, you also have the ability to create DOM elements programmatically using JavaScript.</p>
<p>This is possible because the <code>document</code> object also has the <code>createElement()</code> method, which allows you to create any <code>Element</code> object, which is essentially the tags you write in your HTML file.</p>
<p>For example, you can create a paragraph element like this:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> p = <span class="hljs-built_in">document</span>.createElement(<span class="hljs-string">'p'</span>);
</code></pre>
<p>After you create that element, you can add some content to it using the <code>innerText</code> property:</p>
<pre><code class="lang-js">p.innerText = <span class="hljs-string">'This paragraph is created using JavaScript'</span>;
</code></pre>
<p>Now you need to add it to the existing DOM tree so that it appears on the screen. You can attach the element anywhere inside your existing tree structure.</p>
<p>Suppose you want to add the paragraph to the <code>body</code> tag. Then you need to use the <code>querySelector()</code> method to select the <code>body</code>, and call the <code>append()</code> method on the element:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> p = <span class="hljs-built_in">document</span>.createElement(<span class="hljs-string">'p'</span>);

p.innerText = <span class="hljs-string">'This paragraph is created using JavaScript'</span>;

<span class="hljs-keyword">const</span> body = <span class="hljs-built_in">document</span>.querySelector(<span class="hljs-string">'body'</span>);

body.append(p);
</code></pre>
<p>The paragraph will be added as a child of the <code>body</code> tag as follows:</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">body</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>This paragraph is created using JavaScript<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">body</span>&gt;</span>
</code></pre>
<p>If you want to remove an element, you can call the <code>remove()</code> method from the element you want to remove.</p>
<p>This code will remove the paragraph element:</p>
<pre><code class="lang-js">p.remove();
</code></pre>
<h2 id="heading-insert-element-at-a-specific-position">Insert Element at a Specific Position</h2>
<p>The <code>append()</code> method that we explored above will insert a new element as the last child of the parent element.</p>
<p>If you want to insert the element at a specific position, you can use the <code>insertBefore()</code> method.</p>
<p>Let’s see an easy example. Suppose you have an HTML content as follows:</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">body</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">p</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"first"</span>&gt;</span>The first paragraph<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">body</span>&gt;</span>
</code></pre>
<p>To insert an element before the first paragraph, you need to call the <code>insertBefore()</code> method from the parent element (which is the <code>body</code> tag) and pass two arguments to it:</p>
<ol>
<li>The new element you want to add</li>
<li>The sibling element before which the new element is inserted</li>
</ol>
<p>Here’s an example of creating a second paragraph and inserting it before the first paragraph:</p>
<pre><code class="lang-js"><span class="hljs-keyword">let</span> p2 = <span class="hljs-built_in">document</span>.createElement(<span class="hljs-string">'p'</span>);

p2.innerText = <span class="hljs-string">'The second paragraph'</span>;

<span class="hljs-keyword">let</span> body = <span class="hljs-built_in">document</span>.querySelector(<span class="hljs-string">'body'</span>);
<span class="hljs-keyword">let</span> p1 = <span class="hljs-built_in">document</span>.querySelector(<span class="hljs-string">'#first'</span>);

body.insertBefore(p2, p1);
</code></pre>
<p>As a result of running the script above, the second paragraph will be inserted before the first paragraph:</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">body</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>The second paragraph<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">p</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"first"</span>&gt;</span>The first paragraph<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">body</span>&gt;</span>
</code></pre>
<p>Keep in mind that the DOM doesn’t provide an <code>insertAfter</code> method, because it’s not needed.</p>
<p>You use the <code>append()</code> method to insert an element at the last position, and if you want to control the position, use the <code>insertBefore()</code> method.</p>
<h2 id="heading-manipulating-element-attributes">Manipulating Element Attributes</h2>
<p>The <code>classList</code> object only provide methods to change the <code>class</code> of an element. If you want to change other attributes like <code>id</code>, <code>href</code>, or <code>src</code>, you can use the <code>setAttribute()</code> method.</p>
<p>The <code>setAttribute()</code> method accepts two arguments:</p>
<ol>
<li>The name of the attribute to set</li>
<li>The value of the attribute to set</li>
</ol>
<p>For example, here’s how to set the <code>src</code> attribute of an <code>img</code> tag:</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">img</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"profile-pic"</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"feature-image.png"</span> /&gt;</span>
</code></pre>
<p>Select the <code>img</code> element using <code>querySelector()</code>, then call the <code>setAttribute()</code> method on the element:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> img = <span class="hljs-built_in">document</span>.querySelector(<span class="hljs-string">'#profile-pic'</span>);

img.setAttribute(<span class="hljs-string">'src'</span>, <span class="hljs-string">'new-image.jpg'</span>);
</code></pre>
<p>The <code>src</code> attribute value would be changed as follows:</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">img</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"profile-pic"</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"new-image.jpg"</span> /&gt;</span>
</code></pre>
<p>If you want to the an attribute’s value, you can use the <code>getAttribute()</code> method.</p>
<p>Pass the attribute you want to check as an argument to the method. If the attribute is set, the method returns the value of that attribute as a string. If not, it returns <code>null</code>:</p>
<pre><code class="lang-js">img.getAttribute(<span class="hljs-string">'src'</span>); <span class="hljs-comment">// new-image.jpg</span>
img.getAttribute(<span class="hljs-string">'href'</span>); <span class="hljs-comment">// null</span>
</code></pre>
<p>You can use both <code>setAttribute()</code> and <code>getAttribute()</code> methods to interact with any HTML attributes.</p>
<p>If you want to delete an attribute, use the <code>removeAttribute()</code> method:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> img = <span class="hljs-built_in">document</span>.querySelector(<span class="hljs-string">'#profile-pic'</span>);

<span class="hljs-comment">// Delete the src attribute</span>
img.removeAttribute(<span class="hljs-string">'src'</span>);
</code></pre>
<h2 id="heading-manipulating-data-attributes">Manipulating Data Attributes</h2>
<p>The data attribute is used to store extra information on HTML elements. How you use the data is up to you.</p>
<p>Suppose you have an HTML tag as follows:</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"intro"</span> <span class="hljs-attr">data-attribute-theme</span>=<span class="hljs-string">"light"</span> <span class="hljs-attr">data-session</span>=<span class="hljs-string">"2022"</span>&gt;</span>
  Hello World!
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
</code></pre>
<p>You can access the data attributes from the <code>dataset</code> property of the element above like this:</p>
<pre><code class="lang-js"><span class="hljs-comment">// Select the div</span>
<span class="hljs-keyword">let</span> myDiv = <span class="hljs-built_in">document</span>.querySelector(<span class="hljs-string">'#intro'</span>);

<span class="hljs-comment">// Access the dataset property</span>
<span class="hljs-built_in">console</span>.log(myDiv.dataset.session) <span class="hljs-comment">// 2022</span>

<span class="hljs-comment">// Use camelCase when your data attribute is more than one word</span>
<span class="hljs-built_in">console</span>.log(myDiv.dataset.attributeTheme) <span class="hljs-comment">// light</span>
</code></pre>
<p>If you want to change the attribute value, you can reassign the right <code>dataset</code> property to a new value directly:</p>
<pre><code class="lang-js"><span class="hljs-comment">// Select the div</span>
<span class="hljs-keyword">let</span> myDiv = <span class="hljs-built_in">document</span>.querySelector(<span class="hljs-string">'#intro'</span>);

<span class="hljs-comment">// Change the value of a data attribute</span>
myDiv.dataset.session = <span class="hljs-string">'2023'</span>
</code></pre>
<p>If you want to delete the data attribute, use the <code>removeAttribute()</code> method similar to how you delete a regular attribute:</p>
<pre><code class="lang-js"><span class="hljs-keyword">let</span> myDiv = <span class="hljs-built_in">document</span>.querySelector(<span class="hljs-string">'#intro'</span>);

<span class="hljs-comment">// Remove data-session attribute</span>
myDiv.removeAttribute(<span class="hljs-string">'data-session'</span>);

<span class="hljs-comment">// Remove data-attribute-theme attribute</span>
myDiv.removeAttribute(<span class="hljs-string">'data-attribute-theme'</span>);
</code></pre>
<p>And that’s how you manipulate the data attribute using JavaScript.</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>And that's all for now about DOM element manipulations. At this point, I hope you can see why JavaScript is required to build a modern web application. It allows you to interact and change the content that exists in your website.</p>
<p>This enables a whole lot of dynamic changes to the website you created.</p>
<p>If you enjoyed this article and want to take your JavaScript skills to the next level, I recommend you check out my new book <em>Beginning Modern JavaScript</em> <a target="_blank" href="https://www.amazon.com/dp/B0CQXHMF8G">here</a>.</p>
<p><a target="_blank" href="https://www.amazon.com/dp/B0CQXHMF8G"><img src="https://www.freecodecamp.org/news/content/images/2024/01/beginning-js-cover.png" alt="beginning-js-cover" width="600" height="400" loading="lazy"></a></p>
<p>The book is designed to be easy to understand and accessible to anyone looking to learn JavaScript. It provides a step-by-step gentle guide that will help you understand how to use JavaScript to create a dynamic application.</p>
<p>Here's my promise: <em>You will actually feel like you understand what you're doing with JavaScript.</em></p>
<p>Until next time!</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ HTMLCollection vs NodeList – What's the Difference? ]]>
                </title>
                <description>
                    <![CDATA[ If you're a web developer or have worked with the DOM (Document Object Model), you may have come across the terms HTMLCollection and NodeList before. But what do they mean and when do you need to use them? By the end of this article, you will learn a... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/dom-manipulation-htmlcollection-vs-nodelist/</link>
                <guid isPermaLink="false">66d45dd8182810487e0ce0fd</guid>
                
                    <category>
                        <![CDATA[ DOM ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Front-end Development ]]>
                    </category>
                
                    <category>
                        <![CDATA[ HTML ]]>
                    </category>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Web Development ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Benjamin Semah ]]>
                </dc:creator>
                <pubDate>Thu, 07 Dec 2023 22:11:45 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2023/12/Benjamin-Semah---DevAfterHours.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>If you're a web developer or have worked with the DOM (Document Object Model), you may have come across the terms <code>HTMLCollection</code> and <code>NodeList</code> before. But what do they mean and when do you need to use them?</p>
<p>By the end of this article, you will learn all about <code>HTMLCollection</code> and <code>NodeList</code>.</p>
<h2 id="heading-table-of-contents">Table of Contents</h2>
<ul>
<li><p><a class="post-section-overview" href="#heading-what-is-an-htmlcollection">What is an <code>HTMLCollection</code>?</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-what-is-a-nodelist">What is a <code>NodeList</code></a>?</p>
</li>
<li><p><a class="post-section-overview" href="#heading-similarities-between-htmlcollection-and-nodelist">Similarities between <code>HTMLCollection</code> and <code>NodeList</code></a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-differences-between-htmlcollection-and-nodelist">Differences between <code>HTMLCollection</code> and <code>NodeList</code></a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-which-one-should-you-use">Which one should you use</a>?</p>
</li>
<li><p><a class="post-section-overview" href="#heading-conclusion">Conclusion</a></p>
</li>
</ul>
<p>Let's get started!</p>
<h2 id="heading-what-is-an-htmlcollection">What is an <code>HTMLCollection</code>?</h2>
<p>An <code>HTMLCollection</code> is a list of DOM elements that match certain criteria. For example, they may have the same tag name or class. Or they may be related in a specific context, like children of a particular element.</p>
<p>Here's an example:</p>
<pre><code class="lang-html">  <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"btn"</span>&gt;</span>First button<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"btn"</span>&gt;</span>Second button<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"btn"</span>&gt;</span>Third button<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
</code></pre>
<p>In this example, we have three button elements. Each has a class of <code>btn</code>. Now, let's select the buttons using the <code>getElementsByClassName</code> method.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> buttonElements = <span class="hljs-built_in">document</span>.getElementsByClassName(<span class="hljs-string">'btn'</span>)
<span class="hljs-built_in">console</span>.log(buttonElements)
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/12/Screenshot-2023-12-04-at-8.10.41-AM.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>The <code>getElementsByClassName</code> methods returns an <code>HTMLCollection</code> of the three buttons with the <code>btn</code> class. It looks like an array but it's not. More on that later.</p>
<h2 id="heading-what-is-a-nodelist">What is a <code>NodeList</code>?</h2>
<p>Like the name suggests, a <code>NodeList</code> is a list of nodes. But what is a node? A node is any individual element in the DOM tree. This could be elements, attributes, texts, comments, and so on.</p>
<p>An example of a DOM method that will return a <code>nodeList</code> is <code>querySelectorAll</code>.</p>
<p>Example:</p>
<pre><code class="lang-html">  <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"btn"</span>&gt;</span>First button<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"btn"</span>&gt;</span>Second button<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"btn"</span>&gt;</span>Third button<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
</code></pre>
<p>Using the same example, let's select the buttons with <code>querySelectorAll</code> instead.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> buttonElements = <span class="hljs-built_in">document</span>.querySelectorAll(<span class="hljs-string">'.btn'</span>)
<span class="hljs-built_in">console</span>.log(buttonElements)
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/12/Screenshot-2023-12-04-at-8.33.08-AM.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>This time, the <code>console.log</code> statement prints a <code>NodeList</code>. Again, this is also similar to an array but it isn't quite an array.</p>
<h2 id="heading-similarities-between-htmlcollection-and-nodelist">Similarities between <code>HTMLCollection</code> and <code>NodeList</code></h2>
<p>Now that you know what <code>HTMLCollection</code> and <code>NodeList</code> are, let's look at how they are alike. They both aren't arrays even though they look like one. But they have features that make them have some behaviours of arrays.</p>
<p>You can access the contents of both using zero-based indexing like you would with an array. And you can also use the length property to find the length of both an <code>HTMLCollection</code> and a <code>NodeList</code>.</p>
<p>Example:</p>
<pre><code class="lang-html">  <span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">p</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"paragraph"</span>&gt;</span>First paragraph<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">p</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"paragraph"</span>&gt;</span>Second paragraph<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">p</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"paragraph"</span>&gt;</span>Third paragraph<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
</code></pre>
<p>This is a <code>div</code> with three paragraphs. Let's see examples of accessing the elements with zero-based indexing and also checking the length for both <code>HTMLCollection</code> and <code>NodeList</code>.</p>
<h3 id="heading-example-with-htmlcollection">Example with <code>HTMLCollection</code>:</h3>
<pre><code class="lang-javascript"><span class="hljs-comment">// getElementsByClassName will return an HTMLCollection</span>
<span class="hljs-keyword">const</span> paragraphs = <span class="hljs-built_in">document</span>.getElementsByClassName(<span class="hljs-string">"paragraph"</span>)
<span class="hljs-built_in">console</span>.log(paragraphs)

<span class="hljs-comment">// Use the index to get the first paragraph</span>
<span class="hljs-keyword">let</span> firstParagraph = paragraphs[<span class="hljs-number">0</span>] 
<span class="hljs-built_in">console</span>.log(firstParagraph)

<span class="hljs-comment">// Use the length property</span>
<span class="hljs-built_in">console</span>.log(paragraphs.length)
</code></pre>
<p>The screenshot below shows the results for the three <code>console.log</code> statements.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/12/Screenshot-2023-12-04-at-9.38.09-AM.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Even though the <code>HTMLCollection</code> is not an array, you can still use the index to access the items in the collection. And you can also get the length using the <code>length</code> property.</p>
<p>You will get the same result for a <code>NodeList</code>. To get a <code>NodeList</code>, let's use the <code>querySelectorAll</code> method instead.</p>
<h3 id="heading-example-with-nodelist">Example with <code>NodeList</code>:</h3>
<pre><code class="lang-javascript"><span class="hljs-comment">// querySelectorAll will return a Nodelist</span>
<span class="hljs-keyword">const</span> paragraphs = <span class="hljs-built_in">document</span>.querySelectorAll(<span class="hljs-string">".paragraph"</span>)
<span class="hljs-built_in">console</span>.log(paragraphs)

<span class="hljs-comment">// Use the index to get the first paragraph</span>
<span class="hljs-keyword">let</span> firstParagraph = paragraphs[<span class="hljs-number">0</span>] 
<span class="hljs-built_in">console</span>.log(firstParagraph)

<span class="hljs-comment">// Use the length property</span>
<span class="hljs-built_in">console</span>.log(paragraphs.length)
</code></pre>
<p>Just like the <code>HTMLCollection</code>, the <code>NodeList</code> also uses zero-based indexing. And you can also use the length property on it.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/12/Screenshot-2023-12-04-at-9.55.22-AM.png" alt="Image" width="600" height="400" loading="lazy"></p>
<h2 id="heading-differences-between-htmlcollection-and-nodelist">Differences between <code>HTMLCollection</code> and <code>NodeList</code></h2>
<p>You've seen how an <code>HTMLCollection</code> and a <code>NodeList</code> are alike. But there are also some differences you need to be aware of when working with these two types of collections in the DOM.</p>
<h3 id="heading-elements-nodes-only-vs-all-nodes">Elements nodes only vs all nodes</h3>
<p>Elements nodes are HTML elements like <code>&lt;p&gt;</code>, <code>&lt;div&gt;</code>, <code>&lt;img&gt;</code>, and others. But there are other types of nodes too. For example, text nodes and attribute nodes.</p>
<p>An <code>HTMLCollection</code> will include only element nodes whiles a <code>NodeList</code> includes other node types.</p>
<p>Example:</p>
<pre><code class="lang-javascript">&lt;div&gt;
  This is a text
  &lt;p <span class="hljs-class"><span class="hljs-keyword">class</span></span>=<span class="hljs-string">"paragraph"</span>&gt;First paragraph&lt;/p&gt;
  <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">p</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"paragraph"</span>&gt;</span>First paragraph<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span></span>
&lt;/div&gt;
</code></pre>
<p>Here is a <code>div</code> with a text node and two element nodes (paragraphs). Each paragraph also has a text node.</p>
<p>Assuming you wanted to get only the element nodes in the <code>div</code>, you can use the <code>children</code> property on the <code>div</code>. And it will return an <code>HTMLCollection</code> containing only the element nodes.</p>
<p>But if you wanted all the nodes and not just the element nodes, then you can use the <code>childNodes</code> property to get all the nodes.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> divElement = <span class="hljs-built_in">document</span>.querySelector(<span class="hljs-string">'div'</span>)

<span class="hljs-built_in">console</span>.log(divElement.children) <span class="hljs-comment">// returns an HTMLCollection</span>
<span class="hljs-built_in">console</span>.log(divElement.childNodes) <span class="hljs-comment">// returns a NodeList</span>
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/12/Screenshot-2023-12-04-at-10.59.18-AM.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>The <code>HTMLCollection</code> has two items: the paragraph element nodes. Whilst the <code>NodeList</code> includes the first text and the two paragraphs and their text contents too.</p>
<h3 id="heading-live-collections-vs-static-collections">Live Collections vs Static Collections</h3>
<p>The concepts of "live" and "static" refer to how an <code>HTMLCollection</code> and <code>NodeList</code> behave in response to changes in the document structure.</p>
<h4 id="heading-an-htmlcollection-is-always-live">An <code>HTMLCollection</code> is always live</h4>
<p>What does it mean to say an <code>HTMLCollection</code> is always live? It means when there is a change in the document, it will be automatically updated to reflect the change.</p>
<p>Example:</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>Paragraph One<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>Paragraph Two<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>Paragraph Three<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
</code></pre>
<pre><code class="lang-javascript"><span class="hljs-comment">// returns an HTMLCollection</span>
<span class="hljs-keyword">const</span> paragraphs = <span class="hljs-built_in">document</span>.getElementsByTagName(<span class="hljs-string">'p'</span>)

<span class="hljs-built_in">console</span>.log(<span class="hljs-string">"BEFORE UPDATE: "</span>, paragraphs)

<span class="hljs-keyword">const</span> newParagraph = <span class="hljs-built_in">document</span>.createElement(<span class="hljs-string">'p'</span>)
<span class="hljs-built_in">document</span>.body.appendChild(newParagraph)

<span class="hljs-built_in">console</span>.log(<span class="hljs-string">"AFTER UPDATE: "</span>, paragraphs)
</code></pre>
<p>The code above creates an <code>HTMLCollection</code> called <code>paragraphs</code> using the <code>getElementsByTagName</code> method. And there are two <code>console.log</code> statements. One before a new paragraph is created and appended to the body, and another one after that.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/12/Screenshot-2023-12-06-at-9.04.10-AM.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Before the update, the <code>HTMLCollection</code> had three elements. But after the update, the collection now has four elements, reflecting the change in the document.</p>
<h4 id="heading-a-nodelist-is-sometimes-static">A <code>NodeList</code> is sometimes static</h4>
<p>A <code>NodeList</code> is not always live. It can be static or live depending on how it is generated. For example, a <code>NodeList</code> generated with the <code>querySelectorAll</code> method is static. A change in the document isn't reflected in the <code>NodeList</code>.</p>
<p>Example:</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>Paragraph One<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>Paragraph Two<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>Paragraph Three<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
</code></pre>
<pre><code class="lang-javascript"><span class="hljs-comment">// returns an HTMLCollection</span>
<span class="hljs-keyword">const</span> paragraphs = <span class="hljs-built_in">document</span>.getElementsByTagName(<span class="hljs-string">'p'</span>)

<span class="hljs-built_in">console</span>.log(<span class="hljs-string">"BEFORE UPDATE: "</span>, paragraphs)

<span class="hljs-keyword">const</span> newParagraph = <span class="hljs-built_in">document</span>.createElement(<span class="hljs-string">'p'</span>)
<span class="hljs-built_in">document</span>.body.appendChild(newParagraph)

<span class="hljs-built_in">console</span>.log(<span class="hljs-string">"AFTER UPDATE: "</span>, paragraphs)
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/12/Screenshot-2023-12-06-at-9.09.42-AM.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Because of the static nature of the <code>NodeList</code>, it remains the same even after an update in the document.</p>
<p>Note: in exceptional cases, like when a <code>NodeList</code> is generated with the <code>getElementsByName</code>, that <code>NodeList</code> will be live.</p>
<h3 id="heading-how-to-access-items-in-the-collection">How to Access Items in the Collection</h3>
<p>When accessing elements in an <code>HTMLCollection</code>, you can use any of the following.</p>
<ul>
<li><p>The index of element.</p>
</li>
<li><p>Their <code>id</code> attribute with the <code>namedItem</code> property.</p>
</li>
<li><p>Their <code>name</code> attribute with the <code>namedItem</code> property.</p>
</li>
</ul>
<p>But with a <code>NodeList</code>, you can only access the nodes in the list only by their index.</p>
<pre><code class="lang-javascript">&lt;div id=<span class="hljs-string">"container"</span>&gt;
  <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"btn1"</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"first-name"</span>&gt;</span>First Button<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span></span>
  <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"btn2"</span>&gt;</span>Second Button<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span></span>
  <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"btn3"</span>&gt;</span>Third Button<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span></span>
&lt;/div&gt;
</code></pre>
<p>Here is a <code>div</code> container with three buttons. Note the first button has an id attribute and a name attribute.</p>
<h4 id="heading-example-with-htmlcollection-1">Example with <code>HTMLCollection</code>:</h4>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> container = <span class="hljs-built_in">document</span>.querySelector(<span class="hljs-string">'#container'</span>)
<span class="hljs-keyword">const</span> buttons = container.children <span class="hljs-comment">// returns HTMLCollection</span>

<span class="hljs-built_in">console</span>.log(buttons[<span class="hljs-number">0</span>])<span class="hljs-comment">// using the index</span>
<span class="hljs-built_in">console</span>.log(buttons.namedItem(<span class="hljs-string">"btn1"</span>)) <span class="hljs-comment">// using the id attribute</span>
<span class="hljs-built_in">console</span>.log(buttons.namedItem(<span class="hljs-string">"first-name"</span>)) <span class="hljs-comment">// using the name attribute</span>
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/12/Screenshot-2023-12-04-at-11.57.33-AM.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>All three <code>console.log</code>s successfully return the first button.</p>
<h4 id="heading-example-with-nodelist-1">Example with <code>NodeList</code>:</h4>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> container = <span class="hljs-built_in">document</span>.querySelector(<span class="hljs-string">'#container'</span>)
<span class="hljs-keyword">const</span> buttons = container.childNodes <span class="hljs-comment">// returns a NodeList</span>

<span class="hljs-built_in">console</span>.log(buttons[<span class="hljs-number">1</span>])<span class="hljs-comment">// using the index</span>
<span class="hljs-built_in">console</span>.log(buttons.namedItem(<span class="hljs-string">"btn1"</span>)) <span class="hljs-comment">// throws an error</span>
<span class="hljs-built_in">console</span>.log(buttons.namedItem(<span class="hljs-string">"first-name"</span>)) <span class="hljs-comment">// throws an error</span>
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/12/Screenshot-2023-12-06-at-7.19.56-AM.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Using the same example for a <code>NodeList</code>, the first <code>console.log</code> statement prints the button. But the other two raise a <code>TypeError</code>.</p>
<h3 id="heading-how-to-loop-through-the-collection">How to loop through the collection</h3>
<p>You cannot loop through an <code>HTMLCollection</code> with any of the array methods. Unless you first create an array from the collection.</p>
<p>But with a <code>NodeList</code>, you can use the <code>forEach</code> method to loop through it. But you cannot use other array methods like <code>map</code>, <code>filter</code>, and others without first creating an array from it.</p>
<p>Example:</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"btn"</span>&gt;</span>First button<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"btn"</span>&gt;</span>Second button<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"btn"</span>&gt;</span>Third button<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
</code></pre>
<p>The code below attempts to loop through an <code>HTMLCollection</code> with the <code>forEach</code> method and results in an <code>TypError</code>.</p>
<pre><code class="lang-javascript"><span class="hljs-comment">// returns an HTMLCollection</span>
<span class="hljs-keyword">const</span> allButtons = <span class="hljs-built_in">document</span>.getElementsByClassName(<span class="hljs-string">'btn'</span>) 

allButtons.forEach(<span class="hljs-function"><span class="hljs-params">button</span> =&gt;</span> <span class="hljs-built_in">console</span>.log(button))
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/12/Screenshot-2023-12-06-at-8.04.26-AM.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Let's see another example but with a <code>NodeList</code>.</p>
<pre><code class="lang-javascript"><span class="hljs-comment">// returns a NodeList</span>
<span class="hljs-keyword">const</span> allButtons = <span class="hljs-built_in">document</span>.querySelectorAll(<span class="hljs-string">'.btn'</span>) 

allButtons.forEach(<span class="hljs-function"><span class="hljs-params">button</span> =&gt;</span> <span class="hljs-built_in">console</span>.log(button))
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/12/Screenshot-2023-12-06-at-8.07.27-AM.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>In the example above, the <code>forEach</code> method works successfully on the <code>NodeList</code>.</p>
<p>If for some reason, you still want to loop through an <code>HTMLCollection</code> without first creating an array from it, you can use the <code>for...of</code> statement. Let's use the same buttons example to show how you can do that.</p>
<pre><code class="lang-javascript"><span class="hljs-comment">// returns an HTMLCollection</span>
<span class="hljs-keyword">const</span> allButtons = <span class="hljs-built_in">document</span>.getElementsByClassName(<span class="hljs-string">'btn'</span>)

<span class="hljs-keyword">for</span> (button <span class="hljs-keyword">of</span> allButtons) {
  <span class="hljs-built_in">console</span>.log(button)
}
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/12/Screenshot-2023-12-06-at-8.07.27-AM-1.png" alt="Image" width="600" height="400" loading="lazy"></p>
<h2 id="heading-which-one-should-you-use">Which One Should You Use?</h2>
<p>The question of whether you should use an <code>HTMLCollection</code> or a <code>NodeList</code> depends on the use case or specific context.</p>
<p>If you want a live collection that automatically updates when there's a change in the document, then you should use an <code>HTMLCollection</code>. But if you prefer a static collection that doesn't update with a change in the document, then you should use a <code>NodeList</code>.</p>
<p>Most modern JavaScript frameworks and libraries provide higher-level abstractions, simplifying many DOM manipulation tasks. And you don't need to worry about them.</p>
<p>But having a solid understanding of native DOM collections like <code>HTMLCollection</code> and <code>NodeList</code> remains valuable, especially in scenarios where fine-grained control or compatibility with legacy code is essential.</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>In this article you learned about <code>HTMLCollection</code> and <code>NodeList</code>. You learned about what they are, their similarities and differences. The article also touched on when you should consider using either an <code>HTMLCollection</code> or a <code>NodeList</code>.</p>
<p>Thanks for reading. And happy coding. For more in-depth tutorials, feel free to <a target="_blank" href="https://www.youtube.com/@DevAfterHours">subscribe to my YouTube channel</a>.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Manipulate HTML and CSS Using JavaScript ]]>
                </title>
                <description>
                    <![CDATA[ In JavaScript, the HTML DOM (Document Object Model) represents the structure and content of an HTML document as a tree-like structure. In it, each element, attribute, and text node in the HTML document is represented as a node in the DOM tree.  In th... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/manipulate-html-and-css-using-javascript/</link>
                <guid isPermaLink="false">66b9961017d9592471979c28</guid>
                
                    <category>
                        <![CDATA[ CSS ]]>
                    </category>
                
                    <category>
                        <![CDATA[ DOM ]]>
                    </category>
                
                    <category>
                        <![CDATA[ HTML ]]>
                    </category>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Web Development ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ David Clinton ]]>
                </dc:creator>
                <pubDate>Wed, 19 Jul 2023 18:00:02 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2023/07/pexels-pixabay-276205.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>In JavaScript, the HTML DOM (Document Object Model) represents the structure and content of an HTML document as a tree-like structure. In it, each element, attribute, and text node in the HTML document is represented as a node in the DOM tree. </p>
<p>In this article you're going to learn how you can use that structure to more effectively control the way your HTML elements behave. You'll also learn how to use it to add dynamic interactivity to your users' experience. </p>
<p>This article comes from <a target="_blank" href="https://www.udemy.com/course/complete-lpi-web-development-essentials-exam-study-guide/?referralCode=C92570BCBB38302A9257">my Complete LPI Web Development Essentials Study Guide course</a>. If you'd like, you can follow the video version here:</p>
<div class="embed-wrapper">
        <iframe width="560" height="315" src="https://www.youtube.com/embed/DIg-GoyKUqA" style="aspect-ratio: 16 / 9; width: 100%; height: auto;" title="YouTube video player" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen="" loading="lazy"></iframe></div>
<h2 id="heading-understanding-dom-elements">Understanding DOM elements</h2>
<p>The HTML DOM provides a way to interact with and manipulate the elements of an HTML document using JavaScript. It allows you to access, modify, and add elements dynamically, change styles and classes, handle events, and perform other operations on the document.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/06/642px-DOM-model.svg.png" alt="commons.wikimedia.org/wiki/File:DOM-model.svg using the CC Attribution-Share Alike 3.0 Unported license.\label{fig:dom_model}" width="600" height="400" loading="lazy">
<em>commons.wikimedia.org/wiki/File:DOM-model.svg using the CC Attribution-Share Alike 3.0 Unported license</em></p>
<p>As you can see from that illustration, <code>Document</code> is the top-level object representing an HTML document. It serves as the entry point for accessing the DOM tree and provides methods for navigating and manipulating the document. </p>
<p><code>Element</code> represents an HTML element in the DOM tree. Elements have properties that allow you to access and modify attributes, styles, and content. You can select elements using various methods like:</p>
<ul>
<li><code>getElementById</code></li>
<li><code>getElementsByTagName</code></li>
<li><code>getElementsByClassName</code></li>
<li><code>querySelector</code> </li>
<li><code>querySelectorAll</code></li>
</ul>
<p><code>Node</code> is the base class for all types of nodes in the DOM tree. Nodes can be elements, text nodes, comment nodes, and so on. They have properties and methods for common operations, such as accessing parent and child nodes, manipulating node content, and more.</p>
<p>The DOM provides an event system to handle user interactions and other events. You can attach event listeners to elements to respond to events like clicks, keypresses, and mouse movements.</p>
<h2 id="heading-how-to-interact-with-the-dom-using-javascript">How to Interact with the DOM using JavaScript</h2>
<p>Using JavaScript, you can interact with the HTML DOM to dynamically modify the content and behavior of an HTML page. This allows you to create interactive web applications, implement dynamic user interfaces, and perform various operations on the document based on user actions or programmatic logic.</p>
<p>Here's a simple example that actually does something surprising:</p>
<pre><code class="lang-html"><span class="hljs-meta">&lt;!DOCTYPE <span class="hljs-meta-keyword">html</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">html</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">head</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">title</span>&gt;</span>DOM Manipulation Example<span class="hljs-tag">&lt;/<span class="hljs-name">title</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">head</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">body</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">h1</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"myHeading"</span>&gt;</span>Hello, World!<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">p</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"myParagraph"</span>&gt;</span>This is a paragraph.<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>

  <span class="hljs-tag">&lt;<span class="hljs-name">script</span>&gt;</span><span class="javascript">
    <span class="hljs-comment">// Changing the contents and properties of HTML elements</span>
    <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">"myHeading"</span>).innerHTML = <span class="hljs-string">"New Heading"</span>;
    <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">"myParagraph"</span>).style.color = <span class="hljs-string">"red"</span>;
    <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">"myParagraph"</span>).textContent = <span class="hljs-string">"This is updated."</span>;
  </span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">body</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">html</span>&gt;</span>
</code></pre>
<p>We have an HTML document that contains a heading <code>&lt;h1&gt;</code> element with an id of <code>myHeading</code> and a paragraph <code>&lt;p&gt;</code> element with an id of <code>myParagraph</code>. </p>
<pre><code>  &lt;h1 id=<span class="hljs-string">"myHeading"</span>&gt;Hello, World!&lt;/h1&gt;
  <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">p</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"myParagraph"</span>&gt;</span>This is a paragraph.<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span></span>
</code></pre><p>The JavaScript code within the <code>&lt;script&gt;</code> tags manipulates these elements through the DOM.</p>
<pre><code> &lt;script&gt;
    <span class="hljs-comment">// Changing the contents and properties of HTML elements</span>
    <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">"myHeading"</span>).innerHTML = <span class="hljs-string">"New Heading"</span>;
    <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">"myParagraph"</span>).style.color = <span class="hljs-string">"red"</span>;
    <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">"myParagraph"</span>).textContent = <span class="hljs-string">"This is updated."</span>;
 &lt;/script&gt;
</code></pre><p>The code uses the <code>getElementById</code> method to select elements by their id attribute. It then modifies the elements' contents and properties using the following DOM manipulation techniques:</p>
<ul>
<li><code>innerHTML</code> sets the HTML content inside the selected element. In this case, we change the heading's text to "New Heading".</li>
<li><code>style</code> accesses the CSS styles of the selected element. We set the paragraph's text color to red.</li>
<li><code>textContent</code> sets the text content of the selected element. We update the paragraph's text to "This is an updated paragraph."</li>
</ul>
<p>When we load the HTML document in a web browser, the JavaScript code executes immediately. You'll never see the original HTML styling, but just the "updates" ordered by the JavaScript. The heading text will be "New Heading", the paragraph text color will be red, and the paragraph content will be "This is updated."</p>
<p>This demonstrates how JavaScript can interact with the DOM to dynamically modify the contents and properties of HTML elements based on programmatic logic or user interactions.</p>
<h2 id="heading-how-to-make-your-websites-more-interactive">How to Make Your Websites More Interactive</h2>
<p>You can also trigger changes to an HTML page in response to user activities. In this example, we define two JavaScript functions: <code>showMessage</code> and <code>changeColor</code>. These functions are triggered from HTML elements using the <code>onclick</code> attribute.</p>
<pre><code class="lang-html"><span class="hljs-meta">&lt;!DOCTYPE <span class="hljs-meta-keyword">html</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">html</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">head</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">title</span>&gt;</span>Triggering JavaScript Functions<span class="hljs-tag">&lt;/<span class="hljs-name">title</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">script</span>&gt;</span><span class="javascript">
    <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">showMessage</span>(<span class="hljs-params"></span>) </span>{
      alert(<span class="hljs-string">"Button clicked!"</span>);
    }

    <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">changeColor</span>(<span class="hljs-params"></span>) </span>{
      <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">"myDiv"</span>).style.backgroundColor = <span class="hljs-string">"red"</span>;
    }
  </span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">head</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">body</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">h1</span>&gt;</span>Triggering JavaScript Functions Example<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span>

  <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">onclick</span>=<span class="hljs-string">"showMessage()"</span>&gt;</span>Click me<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"myDiv"</span> <span class="hljs-attr">style</span>=<span class="hljs-string">"width: 200px; height: 200px; background-color: blue;"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">onclick</span>=<span class="hljs-string">"changeColor()"</span>&gt;</span>Change color<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">body</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">html</span>&gt;</span>
</code></pre>
<p>The <code>showMessage</code> function displays an alert box with the message "Button clicked!" when the button is clicked. </p>
<pre><code>    <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">showMessage</span>(<span class="hljs-params"></span>) </span>{
      alert(<span class="hljs-string">"Button clicked!"</span>);
    }
</code></pre><p>The <code>changeColor</code> function changes the background color of the <code>&lt;div&gt;</code> element with the id of <code>myDiv</code> to red when the button is clicked. </p>
<pre><code>    <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">changeColor</span>(<span class="hljs-params"></span>) </span>{
      <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">"myDiv"</span>).style.backgroundColor = <span class="hljs-string">"red"</span>;
    }
</code></pre><p>The HTML code includes a button with the <code>onclick</code> attribute set to <code>showMessage()</code>, which triggers the <code>showMessage</code> function when the button is clicked. </p>
<p>Similarly, there's another button with the <code>onclick</code> attribute set to <code>changeColor()</code>, which triggers the <code>changeColor</code> function when the button is clicked.</p>
<pre><code>  &lt;button onclick=<span class="hljs-string">"showMessage()"</span>&gt;Click me&lt;/button&gt;
  <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"myDiv"</span> <span class="hljs-attr">style</span>=<span class="hljs-string">"width: 200px; height: 200px; background-color: blue;"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
  <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">onclick</span>=<span class="hljs-string">"changeColor()"</span>&gt;</span>Change color<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span></span>
</code></pre><p>When you load the HTML document in a web browser, you'll see the heading, two buttons, and a colored <code>&lt;div&gt;</code> element. Clicking the "Click me" button will trigger the showMessage function and display an alert.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/07/js1.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Clicking the "Change color" button will trigger the <code>changeColor</code> function and change the background color of the <code>&lt;div&gt;</code> element to red.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/07/js2.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>As I'm sure you can guess, this barely scratches the surface on what you can do with DOM. Here's a longer list of DOM-friendly elements and methods and HTML attributes that you can also play with:</p>
<ul>
<li>document.getElementById()</li>
<li>document.getElementsByClassName()</li>
<li>document.getElementsByTagName()</li>
<li>document.querySelector()</li>
<li>document.querySelectorAll()</li>
<li>innerHTML, setAttribute()</li>
<li>removeAttribute()</li>
<li>classList</li>
<li>classList.add()</li>
<li>classList.remove()</li>
<li>classList.toggle()</li>
<li>onClick</li>
<li>onMouseOver</li>
<li>onMouseOut</li>
</ul>
<h2 id="heading-wrapping-up">Wrapping Up</h2>
<p>This was a brief introduction to DOM elements, where you caught a quick glimpse of the how and whys of <em>controlling</em> HTML elements. You also learned how you can add dynamic interactivity and fine-tuned programmatic versatility to your website.</p>
<p><em>This article comes from <a target="_blank" href="https://www.udemy.com/course/complete-lpi-web-development-essentials-exam-study-guide/?referralCode=C92570BCBB38302A9257">my Complete LPI Web Development Essentials Study Guide course</a>.</em> <em>And there's much more technology goodness available at <a target="_blank" href="https://bootstrap-it.com/">bootstrap-it.com</a></em></p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How the Z-index Property Works – Stacking Order of Elements in CSS ]]>
                </title>
                <description>
                    <![CDATA[ If you're a front-end engineer, you've probably faced weird z-index bugs and ended up spending hours trying to fix them.  Change one property here and you have your header flying away from where it was meant to be.  Well, we can attribute this to the... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/z-index-property-and-stacking-order-css/</link>
                <guid isPermaLink="false">66ba597af4ac8da2b2c2e85e</guid>
                
                    <category>
                        <![CDATA[ CSS ]]>
                    </category>
                
                    <category>
                        <![CDATA[ DOM ]]>
                    </category>
                
                    <category>
                        <![CDATA[ HTML ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Web Development ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Franklin Okolie ]]>
                </dc:creator>
                <pubDate>Thu, 09 Feb 2023 22:48:03 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2023/02/stacked-books-1.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>If you're a front-end engineer, you've probably faced weird z-index bugs and ended up spending hours trying to fix them. </p>
<p>Change one property here and you have your header flying away from where it was meant to be. </p>
<p>Well, we can attribute this to the fact that debugging CSS can be quite hard and most times we are doing so blindly. We change properties expecting to see the bugs magically get resolved, but they don't. </p>
<p>Unlike JavaScript that yells at you, giving you hints about what you are doing, CSS is just watches you do rubbish and quietly hopes you figure it out.</p>
<p>One of the many ways to get really good at using CSS is by researching and understanding the mechanism behind some CSS properties you use every day. </p>
<p>This will give you a clear and concise technical know-how about how to implement certain complicated designs. It'll also give you insight on how to resolve some difficult unexplainable bugs you might come across while writing code.</p>
<h2 id="heading-the-problem-with-the-z-index-property-in-css">The Problem with the Z-index Property in CSS</h2>
<p>We can all agree that one of the weirdest, most confusing, and not-so-straightforward CSS properties is the <code>z-index</code>. </p>
<p>When I started learning CSS, I was told by certain instructors that you use <code>z-index</code> when you want a certain DOM (Document Object Model) element to be on top of another. Sounds simple, right? </p>
<p>So I thought – but life experience has a way of letting us know that things aren't always as easy as we thought they'd be.</p>
<p>Not understanding how the <code>z-index</code> property actually works behind the scenes led me down a frustating rabbit hole of having unexplainable bugs relating to <code>z-index</code>. So I started cranking up the <code>z-index</code> value to enormous numbers like the infamous <code>99999</code> to see if I could get the desired result.</p>
<p>Sometimes this works, but other times it doesn't which can be the most annoying thing because it worked the other time. </p>
<p>Another situation is when it works fine at first, but then as you progress in your work, you face yet again the same problem on a different part of your app. So this has you doing the default – cranking up the new <code>z-index</code> up to <code>99999999</code>, an even bigger number than the previous one.</p>
<p>Deep down in your heart as a professional developer, you know this is not right. It is a mess (and personally, I hate messy CSS code). But you also know you have no idea how to approach the problem that will lead to a permanent fix and a win in your <code>z-index</code> wars.</p>
<p>If you are reading this article and want to understand the <code>z-index</code> once and for all, you're in the right place. </p>
<p>I'm about to help demistify the <code>z-index</code> for you. By the time you're done reading through this guide, I hope you'll know how to fix tough <code>z-index</code> bugs and how the <code>z-index</code> actually works. You'll also have a deeper and more fundamental understanding of how browsers render DOM elements and how it relates to the z-index. </p>
<p>Ready? Let's dive right in.</p>
<h2 id="heading-what-is-stacking-context-in-css">What is Stacking Context in CSS?</h2>
<p>Before we even start to understand <code>z-index</code> in all its glory, it'll be to your benefit if you can, for a moment, pretend like you don't know anything about <code>z-index</code>. Forget what you know about it, because from here on, your mental model about <code>z-index</code> is about to change.</p>
<p>There is no smoke without fire, and the fire that powers the <code>z-index</code> property is a concept called <strong>stacking context</strong>. In the next section, we are going to go over the meaning of this term, what it actually means in practice, how it works, and how it relates to <code>z-index</code>.</p>
<p>The stacking context is simply a term we use to define how the browser decides which elements in the DOM come first and which to "render" on top. </p>
<p>When we start writing a block of HTML code, one element after the other, the natural way the browser decides which element comes on top is by checking the order of the DOM elements. See the codepen playground below for more details:</p>
<div class="embed-wrapper">
        <iframe width="100%" height="350" src="https://codepen.io/developeraspire5/embed/eYjavqm" style="aspect-ratio: 16 / 9; width: 100%; height: auto;" title="CodePen embed" scrolling="no" allowtransparency="true" allowfullscreen="true" loading="lazy"></iframe></div>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"green-box"</span>&gt;</span>  <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"pink-box"</span>&gt;</span>  <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"blue-box"</span>&gt;</span>  <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
</code></pre>
<pre><code class="lang-css"><span class="hljs-selector-tag">div</span>{
  <span class="hljs-attribute">width</span>: <span class="hljs-number">100px</span>;
  <span class="hljs-attribute">height</span>: <span class="hljs-number">100px</span>;
  <span class="hljs-attribute">border</span>: <span class="hljs-number">3px</span> solid;

}

<span class="hljs-selector-class">.green-box</span>{
  <span class="hljs-attribute">background-color</span>: green;
}
<span class="hljs-selector-class">.pink-box</span>{
  <span class="hljs-attribute">background-color</span>: hotpink;
  <span class="hljs-attribute">margin-top</span>: -<span class="hljs-number">30px</span>;
  <span class="hljs-attribute">margin-left</span>: <span class="hljs-number">20px</span>;
}
<span class="hljs-selector-class">.blue-box</span>{
  <span class="hljs-attribute">background-color</span>: blue;
  <span class="hljs-attribute">margin-top</span>: -<span class="hljs-number">30px</span>;
  <span class="hljs-attribute">margin-left</span>: <span class="hljs-number">40px</span>;
}
</code></pre>
<p>From the example above, you can see how the browser stacks DOM elements. It does so by simply checking the DOM order of each element, and rendering the latter element on top of the former element. </p>
<p>Think of it this way – how do you stack books? The last one always appears on top, the first one is always the one at the bottom. When you see some stacked books, you already know that the one at the bottom of the stack was the first book to be added to the stack (it started the stack) and the one on the top of the stack was the last to be added to the stack.</p>
<p>In the example above, the blue box is on top because it is the last on the stack as interpreted by the browser, while the green box is at the bottom of the stack because it is the first element in the DOM order.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/02/stacked-books.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>A pictorial representation of how the browser render DOM elements - shown as stacked books.</em></p>
<p>The process of the browser making the decision about which DOM element to be painted and rendered on top the other element is called the <strong>stacking context.</strong> Let's keep this in mind as we will make reference to this term during the rest of the article.</p>
<p>Whenever a stacking context gets created, it is a memo sent to the browser asking it to re-evaluate the DOM elements and render/stack them accordingly.</p>
<p>Now that we have seen and understood what a stacking context means and how the browser renders DOM elements, let's move to other <code>CSS</code> properties that have the ability to affect how the browser makes these decisions.</p>
<h2 id="heading-positioned-elements-in-css">Positioned Elements in CSS</h2>
<p>There is a rule of thumb I want you to always remember as you go about your daily battles with <code>CSS</code>, especially when working with <code>z-index</code> and the stacking context: <strong>"Positioned elements always come on top"</strong>. </p>
<p>What does this mean? Let's find out below:</p>
<div class="embed-wrapper">
        <iframe width="100%" height="350" src="https://codepen.io/developeraspire5/embed/OJwYmNB" style="aspect-ratio: 16 / 9; width: 100%; height: auto;" title="CodePen embed" scrolling="no" allowtransparency="true" allowfullscreen="true" loading="lazy"></iframe></div>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"green-box"</span>&gt;</span>  <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"pink-box"</span>&gt;</span>  <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"blue-box"</span>&gt;</span>  <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
</code></pre>
<pre><code class="lang-css"><span class="hljs-selector-tag">div</span>{
  <span class="hljs-attribute">width</span>: <span class="hljs-number">100px</span>;
  <span class="hljs-attribute">height</span>: <span class="hljs-number">100px</span>;
  <span class="hljs-attribute">border</span>: <span class="hljs-number">3px</span> solid;

}

<span class="hljs-selector-class">.green-box</span>{
  <span class="hljs-attribute">background-color</span>: green;
  <span class="hljs-attribute">position</span>: relative;
}
<span class="hljs-selector-class">.pink-box</span>{
  <span class="hljs-attribute">background-color</span>: hotpink;
  <span class="hljs-attribute">margin-top</span>: -<span class="hljs-number">30px</span>;
  <span class="hljs-attribute">margin-left</span>: <span class="hljs-number">20px</span>;
}
<span class="hljs-selector-class">.blue-box</span>{
  <span class="hljs-attribute">background-color</span>: blue;
  <span class="hljs-attribute">margin-top</span>: -<span class="hljs-number">30px</span>;
  <span class="hljs-attribute">margin-left</span>: <span class="hljs-number">40px</span>;

}
</code></pre>
<p>Here it goes! What happened? In the previous Codepen snippet I shared above, we saw how the browser rendered the boxes. Because of thier DOM order, the green box was farther below the stack than it peers. </p>
<p>But now it is on top of the rest. From the result in the Codepen playground, we can clearly see that the green box is being rendered above the pink box. How?</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/02/image-48.png" alt="Image" width="600" height="400" loading="lazy">
<em>The green box being rendered on top of the rest of the other elements</em></p>
<p>Just like the rule of thumb clearly stated, setting the position property on any element in the DOM tells the browser to kindly re-do its calculations. Then, after those calculations, the browser decided to render the DOM element with the position property on top of any other elements regardless of their DOM order.</p>
<p>It is also worth mentioning that no matter the number of the <code>z-index</code> value we add for the other elements, they will never come on top of a positioned element. Yeah! I know you just had that euphoric revelation moment of "So this was the cause of my bug the other day at work". </p>
<p>You can play around with the playground by adding a <code>z-index</code> property to the other elements and adding a large value and see the result – take it up to 500 even. I assure you none of those elements will get placed on top of the positioned element.</p>
<p><strong>Note:</strong> This doesn't apply to <code>position: static</code>. This is because <code>position: static</code> is the default positioned value assigned by <code>CSS</code> to all DOM elements. You can check it out by editing the playground above to have <code>position: static</code>.</p>
<p>You are probably thinking, "oh well, what if more than one element has the <code>position</code> property set. If you face this scenario, who wins the stacking context war?".</p>
<p>First I would like you to try it out. Try editing the playground above and setting the position properties on the two other elements.</p>
<p>When this happens, we have just evened all the elements by setting a <code>position</code> property. When the browser sees this, it returns to its default way of stacking these elements by following their DOM order. So it again renders the latter over the former just like how we stack up books. Check out the code snippet below to get a proper understanding.</p>
<div class="embed-wrapper">
        <iframe width="100%" height="350" src="https://codepen.io/developeraspire5/embed/oNMRwbQ" style="aspect-ratio: 16 / 9; width: 100%; height: auto;" title="CodePen embed" scrolling="no" allowtransparency="true" allowfullscreen="true" loading="lazy"></iframe></div>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"green-box"</span>&gt;</span>  <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"pink-box"</span>&gt;</span>  <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"blue-box"</span>&gt;</span>  <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
</code></pre>
<pre><code class="lang-css"><span class="hljs-selector-tag">div</span>{
  <span class="hljs-attribute">width</span>: <span class="hljs-number">100px</span>;
  <span class="hljs-attribute">height</span>: <span class="hljs-number">100px</span>;
  <span class="hljs-attribute">border</span>: <span class="hljs-number">3px</span> solid;

}

<span class="hljs-selector-class">.green-box</span>{
  <span class="hljs-attribute">background-color</span>: green;
  <span class="hljs-attribute">position</span>: relative;
}
<span class="hljs-selector-class">.pink-box</span>{
  <span class="hljs-attribute">background-color</span>: hotpink;
  <span class="hljs-attribute">margin-top</span>: -<span class="hljs-number">30px</span>;
  <span class="hljs-attribute">margin-left</span>: <span class="hljs-number">20px</span>;
  <span class="hljs-attribute">position</span>: relative;
}
<span class="hljs-selector-class">.blue-box</span>{
  <span class="hljs-attribute">background-color</span>: blue;
  <span class="hljs-attribute">margin-top</span>: -<span class="hljs-number">30px</span>;
  <span class="hljs-attribute">margin-left</span>: <span class="hljs-number">40px</span>;
  <span class="hljs-attribute">position</span>: relative;

}
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/02/image-49.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>This is how stacking context works in the browser. Adopting this mental model is one of the fundamental ways of truly understanding how <code>z-index</code> works.</p>
<p>From the explanations above and the code snippets we saw, you might be wondering: if the <code>z-index</code> won't work when we try to use it when sibling elements have the <code>position</code> property set, how then do we even use it? </p>
<p>Well, what we just experienced is how the browser decides stacking context by default. <code>z-index</code> is simply a property that allows us to override this default value.</p>
<p>But that comes with some rules of its own. We'll explore this in the section below.</p>
<h2 id="heading-how-to-use-the-z-index-property">How to Use the Z-index Property</h2>
<p>If we are looking to change how things work and opt-out from the default way of how the browser renders and stacks DOM elements, <code>CSS</code> has provided us with a property called <code>z-index</code>. And we can use it to achieve this.</p>
<p>First let's demisfity the almighty <code>z-index</code> property: </p>
<p>The <code>z</code> in <code>z-index</code> refers to the <code>z-axis</code>. <code>z-axis</code> represents the 3 dimensional part of an element.</p>
<ul>
<li><code>x-axis</code> is left and right</li>
<li><code>y-axis</code> is up and down</li>
<li><code>z-axis</code> is forward and backward</li>
</ul>
<p>The mental model is that <code>z-index</code> works like 3D – elements with a higher <code>z-index</code> are elevated and pushed closer to a user's view in the browser so that it looks like they are over/in front of the rest of the other elements. </p>
<p>This is the same way 3D billboards work, by pushing images closer to us optically so that if feels almost as if the characters in these billboards are jumping out of the screen. The <code>z-index</code> shares the same concept with a 3D billboard.</p>
<p>Just like every other CSS property with default values, the default value for the <code>z-index</code> property is <code>auto</code>, which can be interpreted as <code>zero</code>. </p>
<p>When we are using <code>z-index</code> on any DOM element, adding a value of 1 or above is a direct command/signal that tells the browser to push that particular DOM element so that it sits right in front of its siblings.</p>
<p>For us to be able to use <code>z-index</code> effectively, there are some rules guiding how it works. Understanding and properly digesting how these rules apply is very important as it takes you one step closer to being free from the <code>z-index</code> struggle and uneccassary bugs. Check out the code snippet below:</p>
<div class="embed-wrapper">
        <iframe width="100%" height="350" src="https://codepen.io/developeraspire5/embed/PoBvjOP" style="aspect-ratio: 16 / 9; width: 100%; height: auto;" title="CodePen embed" scrolling="no" allowtransparency="true" allowfullscreen="true" loading="lazy"></iframe></div>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"green-box"</span>&gt;</span>  <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"pink-box"</span>&gt;</span>  <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"blue-box"</span>&gt;</span>  <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
</code></pre>
<pre><code class="lang-css"><span class="hljs-selector-tag">div</span>{
  <span class="hljs-attribute">width</span>: <span class="hljs-number">100px</span>;
  <span class="hljs-attribute">height</span>: <span class="hljs-number">100px</span>;
  <span class="hljs-attribute">border</span>: <span class="hljs-number">3px</span> solid;

}

<span class="hljs-selector-class">.green-box</span>{
  <span class="hljs-attribute">background-color</span>: green;
  <span class="hljs-attribute">z-index</span>: <span class="hljs-number">6</span>;
}

<span class="hljs-selector-class">.pink-box</span>{
  <span class="hljs-attribute">background-color</span>: hotpink;
  <span class="hljs-attribute">margin-top</span>: -<span class="hljs-number">30px</span>;
  <span class="hljs-attribute">margin-left</span>: <span class="hljs-number">20px</span>;
}
<span class="hljs-selector-class">.blue-box</span>{
  <span class="hljs-attribute">background-color</span>: blue;
  <span class="hljs-attribute">margin-top</span>: -<span class="hljs-number">30px</span>;
  <span class="hljs-attribute">margin-left</span>: <span class="hljs-number">40px</span>;
}
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/02/image-52.png" alt="Image" width="600" height="400" loading="lazy">
<em>Even after adding a big z-index value to the green box it still doesn't comes on top the pink box</em></p>
<p>Isn't it surprising that, after setting a <code>z-index</code> value of <code>6</code> (a relatively big number for <code>z-index</code>), stacking context doesn't change? </p>
<p>The expectation after doing this is to see the green box being rendered on top of the rest the the boxes (since of course we know that <code>z-index</code> is used to get one element to be on top of the rest).</p>
<p>But in this case it is not working. Moments like this will lead to endless frustration and pulling out of hair and the rhetorical question: "Why aren't you not working?" and eventually a bad day at work. </p>
<p>I introduce you to the first rule of z-index:</p>
<h3 id="heading-z-index-only-works-with-positioned-elements"><code>z-index</code> only works with positioned elements.</h3>
<p>Now, I want you to go edit the playground and set <code>position: relative</code> on the green box and see the result. Try it by editing the Codepen playground above.</p>
<p>If you did, you will immediately see that the green box is now being rendered on top and the browser has re-calculated the stacking context and rendered the DOM elements accordingly via the new information it received. Always remember this first rule. See the first rule in action below:</p>
<div class="embed-wrapper">
        <iframe width="100%" height="350" src="https://codepen.io/developeraspire5/embed/LYBoLrv" style="aspect-ratio: 16 / 9; width: 100%; height: auto;" title="CodePen embed" scrolling="no" allowtransparency="true" allowfullscreen="true" loading="lazy"></iframe></div>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"green-box"</span>&gt;</span>  <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"pink-box"</span>&gt;</span>  <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"blue-box"</span>&gt;</span>  <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
</code></pre>
<pre><code class="lang-css"><span class="hljs-selector-tag">div</span>{
  <span class="hljs-attribute">width</span>: <span class="hljs-number">100px</span>;
  <span class="hljs-attribute">height</span>: <span class="hljs-number">100px</span>;
  <span class="hljs-attribute">border</span>: <span class="hljs-number">3px</span> solid;

}

<span class="hljs-selector-class">.green-box</span>{
  <span class="hljs-attribute">background-color</span>: green;
  <span class="hljs-attribute">z-index</span>: <span class="hljs-number">6</span>;
  <span class="hljs-attribute">position</span>: relative;
}
<span class="hljs-selector-class">.pink-box</span>{
  <span class="hljs-attribute">background-color</span>: hotpink;
  <span class="hljs-attribute">margin-top</span>: -<span class="hljs-number">30px</span>;
  <span class="hljs-attribute">margin-left</span>: <span class="hljs-number">20px</span>;
}
<span class="hljs-selector-class">.blue-box</span>{
  <span class="hljs-attribute">background-color</span>: blue;
  <span class="hljs-attribute">margin-top</span>: -<span class="hljs-number">30px</span>;
  <span class="hljs-attribute">margin-left</span>: <span class="hljs-number">40px</span>;
}
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/02/image-50.png" alt="Image" width="600" height="400" loading="lazy">
<em>After setting a position property on the green box, the z-index now works properly, rendering the green box on top.</em></p>
<p>Next stop is the second rule – but before we go into the details and understand what that rule does, I want to introduce you to a little bug. And I want you to see if you know what is happening and if you can resolve it. </p>
<p>If you can't, don't worry, as I will be explaining it in great detail below.</p>
<div class="embed-wrapper">
        <iframe width="100%" height="350" src="https://codepen.io/developeraspire5/embed/MWBdEXe" style="aspect-ratio: 16 / 9; width: 100%; height: auto;" title="CodePen embed" scrolling="no" allowtransparency="true" allowfullscreen="true" loading="lazy"></iframe></div>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">body</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">header</span>&gt;</span> This is a header <span class="hljs-tag">&lt;/<span class="hljs-name">header</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">main</span>&gt;</span> <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>Hello there I am the main <span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">button</span>&gt;</span> Click me <span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>

  <span class="hljs-tag">&lt;/<span class="hljs-name">main</span>&gt;</span>

<span class="hljs-tag">&lt;/<span class="hljs-name">body</span>&gt;</span>
</code></pre>
<pre><code class="lang-css"><span class="hljs-keyword">@import</span> url(<span class="hljs-string">'https://fonts.googleapis.com/css2?family=Mulish:wght@200..900&amp;display=swap'</span>);
<span class="hljs-selector-tag">body</span>{
  <span class="hljs-attribute">font-family</span>: <span class="hljs-string">'Mulish'</span>, sans-serif;

}
<span class="hljs-selector-tag">header</span> {
  <span class="hljs-attribute">background-color</span>: hotpink;
  <span class="hljs-attribute">text-align</span>: center;
  <span class="hljs-attribute">padding</span>: <span class="hljs-number">30px</span>;
  <span class="hljs-attribute">position</span>: relative;
  <span class="hljs-attribute">z-index</span>: <span class="hljs-number">2</span>;
}

<span class="hljs-selector-tag">main</span> {
  <span class="hljs-attribute">text-align</span>: center;
  <span class="hljs-attribute">background-color</span>: blue;
  <span class="hljs-attribute">color</span>: white;
  <span class="hljs-attribute">padding</span>: <span class="hljs-number">30px</span>;
  <span class="hljs-attribute">position</span>: relative;
  <span class="hljs-attribute">z-index</span>: <span class="hljs-number">1</span>;

}
<span class="hljs-selector-tag">button</span> {
  <span class="hljs-attribute">margin</span>: <span class="hljs-number">0</span> auto;
  <span class="hljs-attribute">width</span>: <span class="hljs-number">90px</span>;
  <span class="hljs-attribute">border</span>: none;
  <span class="hljs-attribute">text-align</span>: center;
  <span class="hljs-attribute">padding</span>: <span class="hljs-number">8px</span>;
  <span class="hljs-attribute">background</span>: white;
  <span class="hljs-attribute">box-shadow</span>: <span class="hljs-number">1px</span> <span class="hljs-number">2px</span> <span class="hljs-number">8px</span> <span class="hljs-built_in">hsl</span>(<span class="hljs-number">0deg</span> <span class="hljs-number">0%</span> <span class="hljs-number">0%</span> / <span class="hljs-number">0.25</span>);
  <span class="hljs-attribute">border-radius</span>: <span class="hljs-number">6px</span>;

  <span class="hljs-attribute">position</span>: absolute;
  <span class="hljs-attribute">z-index</span>: <span class="hljs-number">999999</span>;
  <span class="hljs-attribute">top</span>: -<span class="hljs-number">12px</span>;
}
</code></pre>
<p>From the code snippet above, we have seen yet another <code>z-index</code> issue that can lead to hours of debugging without even knowing what is wrong. </p>
<p>Going through the code, we can see that the <code>button</code> has a outrageous number as its <code>z-index</code> value, and yet it is not sitting on top of the header. This might make you take a step back and reflect on the first rule of <code>z-index</code> and say "But it is a positioned element, why is it not working?".</p>
<p>That brings us to the second rule of <code>z-index</code>:</p>
<h3 id="heading-a-z-index-property-in-an-isolated-stacking-context-is-not-regarded-outside-the-isolated-stacking-context">A <code>z-index</code> property in an Isolated stacking context is not regarded outside the Isolated stacking context.</h3>
<p>What does this mean? Let me break it down:</p>
<p>From the code above, we can see that the <code>main</code> has a <code>position</code> property and also a <code>z-index</code> property. The same thing applies to the <code>header</code> element – the browser has used this value and calculated the stacking context. Since the <code>header</code> has a higher <code>z-index</code> value, it rendered it on top. As simple as that.</p>
<p>Now, the <code>button</code> is a child of  <code>main</code> that also has the <code>position</code> property set. It also a <code>z-index</code> set to even a higher number. </p>
<p>In reference to the second rule, since <code>main</code> has the <code>z-index</code> property which creates something called an <strong>isolated stacking context</strong>, the <code>button</code> element is not regarded when the browser tries to work up the new stacking context.</p>
<p>You can go ahead and remove the <code>z-index</code> property on the <code>main</code> element and see what happens.</p>
<p>If you did that, you likely saw that immediately the <code>button</code> was rendered on top of the <code>header</code> element. </p>
<p>This might be pretty confusing at first, but trust me – when you use it and pratice more with it, it'll stick. I have an analogy to help you create a mental model when you think of this second rule:</p>
<h3 id="heading-captain-analogy">Captain analogy</h3>
<p>In a plane, there are usually 2 pilots, both of whom are equally qualified to fly and captain an airplane. But only one of those 2 pilots are actually chosen to be the captain of that specific flight. As long as the chosen pilot is not missing, sick, or injured during the course of the flight, there is no need for the second pilot to assume being a captain. </p>
<p>But in a situation where something bad happens to the chosen pilot, the second pilot is allowed and mandated to be captain.</p>
<p>Use this same analogy on the <code>main</code> and <code>button</code>, <code>main</code> has already been assigned a captain by having the <code>z-index</code> property. Because of this, the <code>z-index</code> property of the <code>button</code> becomes useless not matter how big we bump up the numbers.</p>
<p>But once we take away the <code>z-index</code> property from the <code>main</code> , the <code>button</code> is now free to be the captain.</p>
<p>Incase you have forgotten what a stacking context means:</p>
<blockquote>
<p>The stacking context is simply a term used to define how the browser decides which elements in the DOM comes first and which to "render" on top.</p>
</blockquote>
<p>We have discussed extensively how stacking context works and how it's created, but below is a summary:</p>
<ul>
<li>Setting a position property (relative, fixed or absolute) on a DOM element.</li>
<li>Setting the <code>z-index</code> property on a DOM element.</li>
<li>Setting <code>opacity</code> to a value less than <code>1</code>.</li>
<li>Using the <code>isolation</code> property.</li>
<li>Using the <code>transform</code>, <code>filter</code>, <code>clip-path</code>, or <code>perspective</code> CSS properties.</li>
</ul>
<p>This simply means that using any of the properties above tells the browser to calculate and see which DOM element should be rendered on top of the rest of the elements.</p>
<p>You can read more about how stacking context works <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Positioning/Understanding_z_index/The_stacking_context">on the MDN</a>.</p>
<h2 id="heading-how-to-debug-the-z-index">How to Debug the Z-Index</h2>
<p>Before we wrap up this article, I want to introduce you to a new <code>property</code> that you can use alongside the <code>z-index</code> property. It helps you deal with stacking contexts in a more pleasant way.</p>
<p>I will do so by introducing a bug so we can see how to fix it. Check the codepen playground below to see:</p>
<div class="embed-wrapper">
        <iframe width="100%" height="350" src="https://codepen.io/developeraspire5/embed/ZEjNaav" style="aspect-ratio: 16 / 9; width: 100%; height: auto;" title="CodePen embed" scrolling="no" allowtransparency="true" allowfullscreen="true" loading="lazy"></iframe></div>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">body</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">header</span>&gt;</span> This is a header <span class="hljs-tag">&lt;/<span class="hljs-name">header</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">main</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">button</span>&gt;</span> Click here to suscribe <span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>Hello there I am the main <span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>Lorem ipsum dolor sit amet consectetur adipisicing elit.   Reiciendis numquam sapiente veniam fugiat. Harum voluptatum est ab similique incidunt,Quae, amet rem. Minima vitae, accusantium corrupti dolorem perferendis qui magnam...[view the full code snippet on the codepen playground above<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>

  <span class="hljs-tag">&lt;/<span class="hljs-name">main</span>&gt;</span>

<span class="hljs-tag">&lt;/<span class="hljs-name">body</span>&gt;</span>
</code></pre>
<pre><code class="lang-css"><span class="hljs-keyword">@import</span> url(<span class="hljs-string">'https://fonts.googleapis.com/css2?family=Mulish:wght@200..900&amp;display=swap'</span>);
<span class="hljs-selector-tag">body</span>{
  <span class="hljs-attribute">font-family</span>: <span class="hljs-string">'Mulish'</span>, sans-serif;

}
<span class="hljs-selector-tag">header</span> {
  <span class="hljs-attribute">background-color</span>: hotpink;
  <span class="hljs-attribute">text-align</span>: center;
  <span class="hljs-attribute">padding</span>: <span class="hljs-number">30px</span>;
  <span class="hljs-attribute">position</span>: sticky;
  <span class="hljs-attribute">top</span>: <span class="hljs-number">0</span>;
  <span class="hljs-attribute">z-index</span>: <span class="hljs-number">2</span>;
}

<span class="hljs-selector-tag">main</span> {
  <span class="hljs-attribute">text-align</span>: center;
  <span class="hljs-attribute">background-color</span>: blue;
  <span class="hljs-attribute">color</span>: white;
  <span class="hljs-attribute">padding</span>: <span class="hljs-number">30px</span>;
  <span class="hljs-attribute">position</span>: relative;
  <span class="hljs-attribute">min-height</span>: <span class="hljs-number">100vh</span>;
}
<span class="hljs-selector-tag">button</span> {
  <span class="hljs-attribute">border</span>: none;
  <span class="hljs-attribute">text-align</span>: center;
  <span class="hljs-attribute">padding</span>: <span class="hljs-number">8px</span>;
  <span class="hljs-attribute">background</span>: white;
  <span class="hljs-attribute">box-shadow</span>: <span class="hljs-number">1px</span> <span class="hljs-number">2px</span> <span class="hljs-number">8px</span> <span class="hljs-built_in">hsl</span>(<span class="hljs-number">0deg</span> <span class="hljs-number">0%</span> <span class="hljs-number">0%</span> / <span class="hljs-number">0.25</span>);
  <span class="hljs-attribute">border-radius</span>: <span class="hljs-number">6px</span>;

  <span class="hljs-attribute">position</span>: sticky;
  <span class="hljs-attribute">top</span>: <span class="hljs-number">0</span>;
  <span class="hljs-attribute">right</span>: <span class="hljs-number">20px</span>;
  <span class="hljs-attribute">margin-left</span>: <span class="hljs-number">100rem</span>;
  <span class="hljs-attribute">z-index</span>: <span class="hljs-number">2</span>;  
}
</code></pre>
<p>If you run the playground above and see the result you will notice an issue there. Here is what I'm trying to do:</p>
<p>We have a blog, and in every blog post we want a floating sticky button that says "Click here to subscribe" because of course we want more viewers subscribed to the blog. </p>
<p>We do this by adding the <code>position: sticky</code> on the button so that it is always floating and in view as the users read the blog post. Once they see it enough, maybe they'll decide to subscribe.</p>
<p>We also want this button to be adherent to the blog post itself, which means as soon as the blog post is no longer in view, there is no reason why the button should be there. Because of this, we made the button a child of the <code>main</code> element which contains the blog post. </p>
<p>While this is true, we also want the button to be above/in front of the content of the blog post, simply floating on top the posts' text. To do this we added a <code>z-index</code> property. Now, because we already have a <code>position</code> property, we were very confident that the button would be stacked on top of the content by the browser.</p>
<p>From the page, we also added a sticky <code>header</code>, so that the <code>header</code> is glued to the page and never scrolls away. We also want the <code>header</code> to be on top on the other elements, so the blog post and any other preceding DOM elements just slip under the header.</p>
<p>To accomplish this, we add a <code>z-index</code> value of <code>2</code> so it is pushed further up the stack and closer to the screen which renders it on top of the other DOM elements.</p>
<p>After doing this and feeling satisfied with our work, we notice that we have a bug (I hate bugs): the button is simply not doing what we want it do. </p>
<p>The button is actually going above the <code>header</code> instead of going below alongside the blog post as we intended. </p>
<p>This is a recipe for further frustration that causes quite a bit of pulling and screaming at the computer screen along with "Why is CSS so difficult?".</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/02/image-44.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Try going over the code and figuring out what the issue really is. Then come back to this article and we will solve it together.</p>
<p>Remember our second rule of <code>z-index</code>? Where we used the Captain analogy to describe how stacking contexts are compared? That is what is playing out here.</p>
<p>Looking at the code, we can see that we created 2 stacking contexts:</p>
<ul>
<li>When we used the <code>positioned</code> and <code>z-index</code> on the <code>header</code> element.</li>
<li>When we used the <code>positioned</code> and <code>z-index</code> on the <code>button</code> element.</li>
</ul>
<p>From the points above we can see that these two elements are the ones being compared by the browser in order to create the correct stacking context.</p>
<p>Also remember we discussed that:</p>
<blockquote>
<p>If two DOM elements have the exact same properties for creating a stacking context, the browser decides which comes out on top by following the DOM order. This means that the latter element comes on top of the former, just like in a stack of books.</p>
</blockquote>
<p>That is how the browser decided that <code>button</code> has has to come on top. When we compare alongside the browser, we see that:</p>
<ul>
<li>The <code>header</code> has <code>position: sticky</code>, but the <code>button</code> also has <code>position: sticky</code>. It doesn't matter which value is used as long as the element is using a <code>position</code> property.</li>
<li>The header has a <code>z-index</code> of 2 (because it wants to come on top), and the button also has a <code>z-index</code> of 2 (because it wants to be above the content of the blog).</li>
</ul>
<p>This has left the browser with no other choice than to decide the winner by following the DOM order, which means that since <code>button</code> is the latter in the DOM order it will come on top of the <code>header</code>. Phew! What a bug.</p>
<p>How do we solve this? We can go back to our Captain analogy:</p>
<blockquote>
<p>On a plane, there are 2 pilots, both of them are equally qualified to fly and captain the plane. But only one of those 2 pilots are actually chosen to be the captain for that flight. As long as the chosen pilot is not missing, sick, or injured, there is no need for the second pilot to assume being a captain.   </p>
<p>But in a situation where something bad happens to the chosen pilot, the second pilot is allowed and mandated to be captain.</p>
</blockquote>
<p>Remember that <code>button</code> is a child of <code>main</code> but the <code>main</code> has no <code>z-index</code>. This means it is not a captain, which also means there is no <strong>isolated stacking context</strong> hindering the <code>button</code>'s <code>z-index</code> property from being disregarded. Instead, the browser will consider it and compare it with the <code>header</code> element to decide which element should be rendered on top.</p>
<p>We can resolve this by applying the second rule of <code>z-index</code> by simply creating an <strong>isolated stacking</strong> context. We do this by adding a <code>z-index</code> property and also setting a <code>position</code> property on the <code>main</code> element.  Let's see this in the code snippet below:</p>
<div class="embed-wrapper">
        <iframe width="100%" height="350" src="https://codepen.io/developeraspire5/embed/yLqWpEZ" style="aspect-ratio: 16 / 9; width: 100%; height: auto;" title="CodePen embed" scrolling="no" allowtransparency="true" allowfullscreen="true" loading="lazy"></iframe></div>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">body</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">header</span>&gt;</span> This is a header <span class="hljs-tag">&lt;/<span class="hljs-name">header</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">main</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">button</span>&gt;</span> Click here to suscribe <span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>Hello there I am the main <span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>Lorem ipsum dolor sit amet consectetur adipisicing elit.   Reiciendis numquam sapiente veniam fugiat. Harum voluptatum est ab similique incidunt,Quae, amet rem. Minima vitae, accusantium corrupti dolorem perferendis qui magnam...[view the full code snippet on the codepen playground above<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>

  <span class="hljs-tag">&lt;/<span class="hljs-name">main</span>&gt;</span>

<span class="hljs-tag">&lt;/<span class="hljs-name">body</span>&gt;</span>
</code></pre>
<pre><code class="lang-css"><span class="hljs-keyword">@import</span> url(<span class="hljs-string">'https://fonts.googleapis.com/css2?family=Mulish:wght@200..900&amp;display=swap'</span>);
<span class="hljs-selector-tag">body</span>{
  <span class="hljs-attribute">font-family</span>: <span class="hljs-string">'Mulish'</span>, sans-serif;

}
<span class="hljs-selector-tag">header</span> {
  <span class="hljs-attribute">background-color</span>: hotpink;
  <span class="hljs-attribute">text-align</span>: center;
  <span class="hljs-attribute">padding</span>: <span class="hljs-number">30px</span>;
  <span class="hljs-attribute">position</span>: sticky;
  <span class="hljs-attribute">top</span>: <span class="hljs-number">0</span>;
  <span class="hljs-attribute">z-index</span>: <span class="hljs-number">2</span>;
}

<span class="hljs-selector-tag">main</span> {
  <span class="hljs-attribute">text-align</span>: center;
  <span class="hljs-attribute">background-color</span>: blue;
  <span class="hljs-attribute">color</span>: white;
  <span class="hljs-attribute">padding</span>: <span class="hljs-number">30px</span>;
  <span class="hljs-attribute">position</span>: relative;
  <span class="hljs-attribute">min-height</span>: <span class="hljs-number">100vh</span>;
  <span class="hljs-attribute">position</span>: relative;
  <span class="hljs-attribute">z-index</span>: <span class="hljs-number">1</span>;
}
<span class="hljs-selector-tag">button</span> {
  <span class="hljs-attribute">border</span>: none;
  <span class="hljs-attribute">text-align</span>: center;
  <span class="hljs-attribute">padding</span>: <span class="hljs-number">8px</span>;
  <span class="hljs-attribute">background</span>: white;
  <span class="hljs-attribute">box-shadow</span>: <span class="hljs-number">1px</span> <span class="hljs-number">2px</span> <span class="hljs-number">8px</span> <span class="hljs-built_in">hsl</span>(<span class="hljs-number">0deg</span> <span class="hljs-number">0%</span> <span class="hljs-number">0%</span> / <span class="hljs-number">0.25</span>);
  <span class="hljs-attribute">border-radius</span>: <span class="hljs-number">6px</span>;

  <span class="hljs-attribute">position</span>: sticky;
  <span class="hljs-attribute">top</span>: <span class="hljs-number">0</span>;
  <span class="hljs-attribute">right</span>: <span class="hljs-number">20px</span>;
  <span class="hljs-attribute">margin-left</span>: <span class="hljs-number">100rem</span>;
  <span class="hljs-attribute">z-index</span>: <span class="hljs-number">2</span>;  
}
</code></pre>
<p>Tada! Solved.</p>
<p>Now we have handed the captain mantle to <code>main</code> who is a parent to the <code>button</code>. This forces the <code>button</code> to step aside. And since the <code>z-index</code> on the <code>header</code> is <code>2</code> (which is a bigger number than <code>1</code> which we set on the <code>main</code>), the <code>button</code> is now going under the header alongside the blog post. </p>
<p>This is because, just like the second rule of <code>z-index</code> explained, the <code>z-index</code> value on the <code>button</code> no longer has any effect on the stacking context decision made by the browser.</p>
<p>Here are the 2 rules of the <code>z-index</code> property again:</p>
<ol>
<li><strong><code>z-index</code> only works with positioned elements.</strong></li>
<li><strong>A <code>z-index</code> property in an isolated stacking context is not regarded outside the isolated stacking context.</strong></li>
</ol>
<h3 id="heading-how-to-use-the-isolation-property">How to use the isolation property</h3>
<p>While the above code clearly solved our problem, we are still left with something every developer hates – that is, having littered <code>z-index</code> all over our codebase, we can go on vacation for a month, come back to our codebase, and encounter yet another <code>z-index</code> bug. We might forget what some particular <code>z-index</code> value was even supposed to do. Then we'll remove it which will plunge ourselves into another endless round of bug fighting.</p>
<p>Instead of using <code>position: relative; z-index: 1;</code> on our <code>main</code> element to create the <strong>isolated stacking context</strong>, we can simply do this instead:   </p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/02/image-46.png" alt="Image" width="600" height="400" loading="lazy">
<em>Using the isolation property to solve the bug</em></p>
<pre><code class="lang-css"><span class="hljs-selector-tag">main</span> {
  <span class="hljs-attribute">isolation</span>: isolate;
}
</code></pre>
<p>The <code>isolation</code> property does only one thing which is: it creates a stacking context.</p>
<p>This is the simplest way to create a stacking context. It can be useful when you want to prevent the <code>z-index</code> values of child elements from affecting the layout of a webpage (except, of course, when we want it to do so). This property allows us achieve this without the burden of having the <code>z-index</code> every where in our code.</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>We have reached the end of this article. Hopefully you now understand the underlying mechanism behind how the browser stacks elements in the DOM (called a stacking context). You should also know how the <code>z-index</code> propery works, <code>z-index</code> rules, how to effectively use these rules.</p>
<p>I hope you learned a lot from this article, and I am looking forward to seeing you win every <code>z-index</code> battle you might face in future. You can always come back to this post and read it again.</p>
<p>For more CSS tips, follow me on <a target="_blank" href="https://twitter.com/developeraspire">Twitter</a>.</p>
<p>Thanks for reading! See you next time.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How the Document Object Model Works in JavaScript – DOM Tutorial for Beginners ]]>
                </title>
                <description>
                    <![CDATA[ The Document Object Model (DOM) is an essential part of web development. It provides a way for programmers to interact with and manipulate the structure of a website.  With the help of the DOM, developers can access and change the different parts of ... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/javascript-dom/</link>
                <guid isPermaLink="false">66bd90522384aa6dc0878d5f</guid>
                
                    <category>
                        <![CDATA[ Document Object Model ]]>
                    </category>
                
                    <category>
                        <![CDATA[ DOM ]]>
                    </category>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Web Development ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Boateng Dickson ]]>
                </dc:creator>
                <pubDate>Thu, 19 Jan 2023 15:21:29 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2023/01/JavaScript-DOM-cover-image1.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>The Document Object Model (DOM) is an essential part of web development. It provides a way for programmers to interact with and manipulate the structure of a website. </p>
<p>With the help of the DOM, developers can access and change the different parts of a webpage. This allows them to create dynamic and interactive websites, where user interactions can trigger changes in the page's layout and content. </p>
<p>Understanding the DOM is crucial for creating responsive and user-friendly websites. So in this article, we will delve deeper into what the DOM can do and how you can use it in JavaScript.</p>
<h2 id="heading-what-is-the-dom">What is the DOM?</h2>
<p>The DOM, or Document Object Model, is like a map of a website. Just like how a map shows you where all the streets and buildings are in a city, the DOM shows you where everything is on a website. </p>
<p>The DOM helps your computer understand the different parts of a website and how they are put together. </p>
<p>Just like you can use a map to find your way around a city, programmers can use the DOM to find different parts of a website and change their properties. For example, they can make a button change color when a user hovers over it or make pictures move around on the screen.</p>
<p>The DOM is like a big puzzle. But using JavaScript, we can move the puzzle pieces around and make a website look and work however we want it to work.</p>
<h2 id="heading-the-dom-javascript">The DOM + JavaScript</h2>
<p>JavaScript is a programming language that helps us interact with the DOM. The DOM and JavaScript are like two friends that work together to make websites cool and interactive. Again, the DOM is like a big map that shows where all the different parts of the website are located.</p>
<p>On the other hand, JavaScript is like a magic wand that can change a website by using the map (DOM) to find the different parts of the website. It can make a button change color when you click on it or make a picture move to a different spot on the page. </p>
<p>Together, the DOM and JavaScript make the website come alive and respond to what you do, like moving your mouse or clicking on a button. </p>
<p>In summary, the DOM is like a map that shows where everything is and JavaScript is like a magic wand that can change things on that map.</p>
<h2 id="heading-dom-structure-understanding-the-dom-tree">DOM Structure – Understanding the DOM Tree</h2>
<p>Imagine a website is like a big book, and each page in that book represents a different part of the website. The DOM tree is like a table of contents for that book. It shows you all the different parts of the website, and how they are organized. </p>
<p>Each part of the website is called an "element" and these elements are arranged in a tree-like structure. </p>
<p>The top of the tree is called the "root" and it represents the entire website. From there, the tree branches out into different sections, like the headings, paragraphs, images, and others that make up the entire website.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/01/DOM-tree-5.png" alt="Image" width="600" height="400" loading="lazy">
<em>Illustration of the DOM tree</em></p>
<p>Just like how the table of contents in a book helps you find specific pages, the DOM tree helps computers find specific elements on a website. In addition, it allows developers to access and change those elements, so they can make the website interactive. </p>
<p>In short, the DOM tree represents the structure of a website in a way that computers can understand. Developers can use it to access and manipulate different elements in that structure to create dynamic web pages.</p>
<h2 id="heading-how-to-access-the-dom">How to Access the DOM</h2>
<p>Accessing elements in the DOM means finding specific parts of a website and changing or manipulating them. </p>
<p>To access an element on a website, you need to know the specific element you want to access. </p>
<p>JavaScript provides different methods to access the elements in the DOM, such as <code>getElementById</code>, <code>getElementsByTagName</code>, <code>querySelector</code>, and <code>querySelectorAll</code>. </p>
<p>These methods allow you to find an element based on its <code>id</code>, <code>tagname</code>, or <code>classname</code> and select it for manipulation. </p>
<p>For example, you can access a button on a webpage and change its text or color when a user clicks on it. Or, you can access an image on a webpage and change it to a different image when a user hovers over it. </p>
<p>Here's an example of how you might use the DOM to access an element on a webpage: </p>
<p>Let's say you have a webpage that displays a list of students and you want to change the background color of a specific student when they are clicked. </p>
<p>You can use the DOM method <code>getElementById</code> to access the specific element that represents the student and then use the <code>style</code> property in JavaScript to change the background color of that element.</p>
<p>Here's how that might look:</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"student-list"</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"student-1"</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"student"</span>&gt;</span>John<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"student-2"</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"student"</span>&gt;</span>Alice<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"student-3"</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"student"</span>&gt;</span>Bob<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
</code></pre>
<pre><code class="lang-css"><span class="hljs-selector-class">.student</span> {
  <span class="hljs-attribute">padding</span>: <span class="hljs-number">40px</span>;
  <span class="hljs-attribute">margin-bottom</span>: <span class="hljs-number">10px</span>;
  <span class="hljs-attribute">cursor</span>: pointer;
}
<span class="hljs-selector-class">.student</span><span class="hljs-selector-pseudo">:hover</span> {
  <span class="hljs-attribute">background-color</span>: <span class="hljs-number">#f1f1f1</span>;
}
</code></pre>
<pre><code class="lang-javascript"><span class="hljs-keyword">let</span> student1 = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">"student-1"</span>);

student1.addEventListener(<span class="hljs-string">"click"</span>, <span class="hljs-function">() =&gt;</span> {
  student1.style.backgroundColor = <span class="hljs-string">"lightblue"</span>;
});
</code></pre>
<p>In this example, JavaScript is using the <code>getElementById</code> method to select the element with the id "student-1" and it changes its <code>backgroundColor</code> property to "light blue" when you click on it.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/01/Document_4.gif" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Similarly, you can use <code>getElementsByClassName</code> to select all elements with a specific class and <code>querySelector</code> to select an element based on a CSS selector.</p>
<p>This is just a basic example, but it illustrates how you can use the DOM to access specific elements on a webpage and change their properties in response to user interaction.</p>
<h2 id="heading-how-to-add-remove-and-modify-dom-elements">How to Add, Remove, and Modify DOM Elements</h2>
<p>Adding, removing, and modifying elements in the DOM refers to adding new elements to a webpage, removing existing elements, and changing the properties of existing elements.</p>
<p>For example, if you want to add a new button to a webpage, you would use JavaScript to create a new element and then use the DOM to add that element to the webpage. Similarly, if you want to remove an element, you would use the DOM to find the element and then delete it.</p>
<p>Modifying elements also involves making changes to the properties of an existing element. For example, you could use the DOM to change the text inside a button.</p>
<p>Here’s how you can express this in code.:</p>
<pre><code class="lang-html">    <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"wrapper"</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"btn-wrapper"</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"create-btn"</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"btn"</span>&gt;</span>Create new button<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
</code></pre>
<pre><code class="lang-css"><span class="hljs-selector-class">.btn-wrapper</span> {
  <span class="hljs-attribute">display</span>: flex;
  <span class="hljs-attribute">height</span>: <span class="hljs-number">100vh</span>;
  <span class="hljs-attribute">justify-content</span>: center;
  <span class="hljs-attribute">align-items</span>: center;
  <span class="hljs-attribute">gap</span>: <span class="hljs-number">10px</span>;
  <span class="hljs-attribute">flex-wrap</span>: wrap;
}
</code></pre>
<pre><code class="lang-javascript"><span class="hljs-keyword">let</span> createButton = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">"create-btn"</span>);
<span class="hljs-keyword">let</span> wrapper = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">"wrapper"</span>);

createButton.addEventListener(<span class="hljs-string">"click"</span>, <span class="hljs-function">() =&gt;</span> {
  <span class="hljs-keyword">let</span> newButton = <span class="hljs-built_in">document</span>.createElement(<span class="hljs-string">"button"</span>);
  newButton.innerHTML = <span class="hljs-string">"Click me"</span>;
  wrapper.appendChild(newButton);
});
</code></pre>
<p>In the above example, we are creating a new button element and setting the text inside the button to "Click me". Then we're using the <code>appendChild</code> method to add this new button element to the webpage.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/01/Document.gif" alt="Image" width="600" height="400" loading="lazy"></p>
<h2 id="heading-recap">Recap</h2>
<p>The Document Object Model (DOM) is an essential tool for creating interactive, dynamic web pages using JavaScript. It allows developers to access and manipulate the contents of a webpage in real time. </p>
<p>Understanding the DOM tree and how to access, add, remove, and modify elements is crucial for JavaScript developers.</p>
<p>We've seen how the DOM represents a webpage as a tree of objects and how we can use different methods like <code>getElementById</code>, <code>getElementsByTagName</code>, <code>querySelector</code>, and <code>querySelectorAll</code> to access specific elements on a webpage. With these methods, we can change the content, style, or layout of a webpage after it has loaded in the browser. </p>
<p>Additionally, we've seen how to add new elements to a webpage, remove existing elements, and change the properties of existing elements.</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>I hope this article has given you a better understanding of the Document Object Model and how to use it to create dynamic web pages. </p>
<p>Remember that the DOM is a powerful tool that you can use to create amazing websites, so don't be afraid to experiment and try new things.</p>
<p>Thanks for reading! Kindly share this article and follow me on  Twitter <a target="_blank" href="https://twitter.com/alege_dev">@alege_dev</a> for updates on future posts.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ What is XSS? How to Protect Your Website from DOM Cross-Site Scripting Attacks ]]>
                </title>
                <description>
                    <![CDATA[ By Andrej Kovacevic Website security issues and vulnerabilities are a global problem as cyber security vulnerabilities are increasing. We have seen a major rise in the average number of these cases in the past few years, and 2021 saw an all-time high... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-protect-against-dom-xss-attacks/</link>
                <guid isPermaLink="false">66d45da34a7504b7409c3332</guid>
                
                    <category>
                        <![CDATA[ Application Security ]]>
                    </category>
                
                    <category>
                        <![CDATA[ DOM ]]>
                    </category>
                
                    <category>
                        <![CDATA[ information security ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Web Security ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Tue, 03 Jan 2023 19:51:56 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2022/09/xss-code-case.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Andrej Kovacevic</p>
<p><strong>Website security issues</strong> and vulnerabilities are a global problem as cyber security vulnerabilities are increasing. We have seen a major rise in the average number of these cases in the past few years, and 2021 saw an all-time high.</p>
<p>So in this tutorial, we are going to talk about DOM XSS cross-site scripting security issues and what impact they can have on your data. Make sure you read till the end. Let's begin by brushing up on some basics about DOM XSS cross-site script security.</p>
<h2 id="heading-what-is-cross-site-scripting">What is Cross-Site Scripting?</h2>
<p>Cross-site scripting, also called XSS, is a <a target="_blank" href="https://www.wix.com/blog/2022/01/website-security/">website security issue</a> that compromises user information and data when those people use a vulnerable application. The attacker can use this to circumvent the origin policy, which separates two websites from one another.</p>
<p>Attackers may use XSS to pretend to be a user, perform actions that a user would, and gain access to the user’s information. This can also allow the attackers to gain full access to the user’s information if they have permissions and privileges. It can also take over the complete actions and performance of the website if this continues.</p>
<p>To help you better understand these types of attacks, we are going to discuss some fundamentals of how XSS operates and what it does.</p>
<h2 id="heading-how-does-xss-work">How Does XSS Work?</h2>
<p>Cross-site scripting uses technology to manipulate a vulnerable site so that it sends dangerous JavaScript to users. This allows the attacker to gain complete access to the site when the script gains access to the user’s system. But the user needs to execute the JavaScript for this first.</p>
<h3 id="heading-types-of-xss-attacks">Types of XSS Attacks</h3>
<h4 id="heading-reflected-xss">Reflected XSS:</h4>
<p>This malicious script comes from the HTTP request. This is the most basic type of XSS attack, where an application could receive malicious data and reflect it immediately towards the user. </p>
<p>The attacker’s payload must be part of the request sent to a server, which is then reflected and executed onto the user’s application. </p>
<p>One example of this would be an attacker convincing someone to click on a phishing link before it takes effect.</p>
<h4 id="heading-stored-xss">Stored XSS:</h4>
<p>This malicious script comes from the database of the website. The attacker inputs the malicious request onto the server where it could stay permanently unless manually addressed. </p>
<p>For example, the attacker could input a malicious script into a comment field, which would be on display for everyone who visits the page. Even without directly engaging with the script, page visitors could fall victim to this attack.</p>
<h4 id="heading-dom-based-xss">DOM-based XSS:</h4>
<p>This more advanced vulnerability exists in client code and not on the server code. DOM-based XSS is neither reflected nor stored onto the server, but exists in a page’s Document Object Model (DOM). The web application reads the malicious code and executes it in the browser as part of the DOM, which is more difficult to detect as it doesn’t come through the server.</p>
<p>The <strong>security vulnerabilities</strong> involved in DOM XSS attacks are a serious concern for most websites. We are going to talk about some of the most common risks that you have on open source web building platforms such as WordPress with regard to DOM - XSS hacks.</p>
<p>This allows the attacker to execute malicious JavaScript code in the victim's browser, potentially allowing the attacker to steal sensitive information or perform other harmful actions on the victim's behalf.</p>
<p>Here is an example of a DOM-based XSS attack:</p>
<pre><code class="lang-javascript">&lt;script&gt;
 <span class="hljs-comment">// This function is intended to take a user supplied URL and display it on the page</span>
 <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">displayURL</span>(<span class="hljs-params">url</span>) </span>{
  <span class="hljs-comment">// The URL is passed through innerHTML, which can execute JavaScript code</span>
  <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">"display"</span>).innerHTML = url;
 }
&lt;/script&gt;

&lt;!-- User supplied input is passed to the displayURL <span class="hljs-function"><span class="hljs-keyword">function</span> --&gt;
&lt;<span class="hljs-title">p</span>&gt;<span class="hljs-title">Enter</span> <span class="hljs-title">a</span> <span class="hljs-title">URL</span> <span class="hljs-title">to</span> <span class="hljs-title">display</span>: &lt;<span class="hljs-title">input</span> <span class="hljs-title">type</span>="<span class="hljs-title">text</span>" <span class="hljs-title">id</span>="<span class="hljs-title">user</span>-<span class="hljs-title">input</span>" /&gt;&lt;/<span class="hljs-title">p</span>&gt;
&lt;<span class="hljs-title">button</span> <span class="hljs-title">onclick</span>="<span class="hljs-title">displayURL</span>(<span class="hljs-params">document.getElementById(<span class="hljs-string">'user-input'</span>).value</span>)"&gt;
 <span class="hljs-title">Display</span> <span class="hljs-title">URL</span>
&lt;/<span class="hljs-title">button</span>&gt;

&lt;!-- <span class="hljs-title">The</span> <span class="hljs-title">URL</span> <span class="hljs-title">is</span> <span class="hljs-title">displayed</span> <span class="hljs-title">in</span> <span class="hljs-title">this</span> <span class="hljs-title">div</span> --&gt;
&lt;<span class="hljs-title">div</span> <span class="hljs-title">id</span>="<span class="hljs-title">display</span>"&gt;&lt;/<span class="hljs-title">div</span>&gt;</span>
</code></pre>
<p>Remember that this tutorial is purely for educational purposes, to help you recognize and defend against XSS. You shouldn't use this information to perform any of these sorts of attacks.</p>
<h2 id="heading-dom-xss-wordpress-vulnerabilities">DOM XSS – WordPress Vulnerabilities</h2>
<p>The main target of DOM XSS attacks on WordPress is its users. Users enter their details, accounts, and site credentials to access their WordPress sites and this is what the DOM XSS attacks aim to compromise online. The attackers can use DOM XSS to get access to user information and details with a single click.</p>
<p>This also includes your cookies, information, and others, making it one of the most common <strong>WordPress security vulnerabilities.</strong></p>
<p>Following are some of the top WordPress website security issues you should bear in mind to ensure better cross-site script security.</p>
<h3 id="heading-accessing-a-users-private-information">Accessing a User's Private Information</h3>
<p>One of the most common WordPress security vulnerabilities involved with DOM XSS attacks is that attackers can gain useful information and even completely take over a user’s site. This can often make things escalate fast and cause complete data compromise.</p>
<h3 id="heading-impersonating-a-user">Impersonating a User</h3>
<p>Attackers can pretend to be the user, to interact with the victim’s online users, clients, and customers to gain their information.</p>
<h3 id="heading-compromising-a-site">Compromising a Site</h3>
<p>Another common cross-site scripting security issue with websites is that these attacks can compromise the website and take access from the user. This includes displaying deviating content on the site (or content that is not originally from the site).</p>
<p>Other cases may involve changing the way WordPress looks online. Other people may also exploit the website by installing explicit content.</p>
<h3 id="heading-social-engineering">Social Engineering</h3>
<p>In more severe cases, attackers may impact the WordPress site through phishing attempts. This is a common concern for web builder security vulnerabilities that we will discuss shortly.</p>
<p>The impact of XSS cross script-security issues varies for each website. However, WordPress sites are usually at a higher risk of these kinds of compromises because users save their personal information on the website. The risk increases further if the user is an admin, as the attacker can compromise the complete WordPress site.</p>
<h2 id="heading-dom-xss-and-closed-code-web-builder-platforms">DOM XSS and Closed Code Web Builder Platforms</h2>
<p>Website builders such as Weebly, Squarespace, Webflow and Wix, unlike WordPress, are non-open source platforms. They allow users to intuitively create websites for their businesses via drag and drop DIY features without any coding or design experience. They also work hard to protect their users' security. </p>
<p>There are tons of useful tools, options, easy-to-integrate dashboards, and hosting opportunities available for users instilling their trust in these platforms. Website security issues are of course a major concern for the majority of the users on these platforms.</p>
<p>Many website builders try their best to protect the sites of their users from <a target="_blank" href="https://techbullion.com/how-to-secure-your-online-store-from-hackers/">hacker threats</a>. But out of all of the website builders available, I believe that Wix follows the NIST framework for cyber security the best and has become a major contributor to improvements in this field. </p>
<p>Wix protects users on their sites from being vulnerable to these kinds of attacks online with tools such as:</p>
<ul>
<li>Third-party updates that project against DOM XSS attacks</li>
<li>A secure Sockets Layer that protects against unwanted access for users on site</li>
<li>Round-the-clock secure web hosting which protects users against any kind of unwanted logins or phishing attempts.</li>
<li>Granting its users admin privileges, which restrict site access and control to the original owner only</li>
<li>Highlighting weak passwords and suggesting more difficult-to-decipher passwords.</li>
</ul>
<h2 id="heading-ways-to-protect-against-xss-attacks">Ways to Protect Against XSS Attacks</h2>
<p>Defending your system and users against XSS attacks often requires a multifaceted approach to ensure that your servers and applications are protected against various types of attacks.</p>
<p>The best way to defend against XSS attacks is to properly sanitize user input. This means making sure that any user input is properly encoded so that it cannot be interpreted as code by the browser. </p>
<p>Additionally, you can use a web application firewall (WAF) to help identify and block XSS attacks. It's also a good idea to keep your software and web applications up to date, as many XSS vulnerabilities can be mitigated by simply applying the latest security patches.</p>
<h3 id="heading-input-validation">Input Validation</h3>
<p>This programming technique ensures that only properly-formatted data can enter a software system. Websites can either allow or block certain values to ensure that no XSS can penetrate their servers.</p>
<h3 id="heading-escaping-or-encoding-user-input">Escaping or Encoding User Input</h3>
<p>Encoding and escaping changes user input to make them safer for the system. Encoding replaces special characters with more harmless equivalents (for example, translating &lt; to &lt;), while escaping adds special characters to protect against injection attacks.</p>
<h3 id="heading-implementing-a-content-security-policy-csp">Implementing a Content Security Policy (CSP)</h3>
<p>Content security policies help administrators mitigate XSS attacks by restricting the resources a page can load at a given time. These resources can include scripts and images that could potentially harm clients and servers.</p>
<h2 id="heading-bottom-line">Bottom Line</h2>
<p>DOM XSS cross-site scripting security issues are a serious concern for users on websites. But closed code web building platforms provide features like admin privileges, password best practices, 3<sup>rd</sup> party updates, and much more. These features make them a more secure website building option than many open code platforms.</p>
<p>You can also prevent XSS attacks by filtering input once it arrives. You can do this by ensuring that only valid input is accepted.</p>
<p>When encoding data on output, the process should be done in HTTP responses so it will not be read as active content. More complex coding might be required, such as applying combinations of URL, JavaScript, CSS, and HTML encoding, depending on the context of output.</p>
<p>Keep response headers in check so browsers will have an appropriate interpretation of content.</p>
<p>Finally, use Content Security Policy (CSP) to minimize the severity of XSS attacks.</p>
<pre><code>&lt;meta http-equiv=<span class="hljs-string">"Content-Security-Policy"</span> content=<span class="hljs-string">"default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval'; style-src 'self' 'unsafe-inline';"</span>&gt;
</code></pre><p>This CSP will allow your website to load scripts and styles from the same origin (that is, your own website), but it will block scripts and styles from external sources. It will also allow the use of inline scripts and styles, but it will block eval() statements, which can be used to execute arbitrary code.</p>
<p>Of course, this is just a simple example, and you can customize your CSP to suit your specific needs. For more information on how to use CSPs to defend against XSS attacks, you can refer to the Content Security Policy Level 2 specification.</p>
<p><em>Feature image via Unsplash (Florian Olivo).</em></p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Event Bubbling in JavaScript – How Event Propagation Works with Examples ]]>
                </title>
                <description>
                    <![CDATA[ By Dillion Megida HTML elements receive different types of events, from click, to blur, to scroll, and so on.  One behavior these events have in common is Event Bubbling. I'll explain what this behavior means in this article. I also made a video vers... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/event-bubbling-in-javascript/</link>
                <guid isPermaLink="false">66d84eedda89a73e2ddf5790</guid>
                
                    <category>
                        <![CDATA[ Document Object Model ]]>
                    </category>
                
                    <category>
                        <![CDATA[ DOM ]]>
                    </category>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Mon, 31 Oct 2022 21:04:17 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2022/10/1.-event-bubbling-js.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Dillion Megida</p>
<p>HTML elements receive different types of events, from click, to blur, to scroll, and so on. </p>
<p>One behavior these events have in common is Event Bubbling. I'll explain what this behavior means in this article.</p>
<p>I also made a video version of this article which <a target="_blank" href="https://www.youtube.com/watch?v=KaHZdW02Tg0">you can watch here</a>.</p>
<h2 id="heading-what-is-event-bubbling">What is Event Bubbling?</h2>
<p>Event Bubbling is a concept in the DOM (Document Object Model). It happens when an element receives an event, and that event bubbles up (or you can say is transmitted or propagated) to its parent and ancestor elements in the DOM tree until it gets to the root element.</p>
<p>This is the default behavior of events on elements unless you stop the propagation <a class="post-section-overview" href="#how-to-stop-event-bubbling">which I'llexplain at the end of this article</a></p>
<p>Let's look at an example so I can better explain how event bubbling works.</p>
<p>The HTML:</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">body</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">span</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">button</span>&gt;</span>Click Me!<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">body</span>&gt;</span>
</code></pre>
<p>The CSS:</p>
<pre><code class="lang-css"><span class="hljs-selector-tag">body</span> {
  <span class="hljs-attribute">padding</span>: <span class="hljs-number">20px</span>;
  <span class="hljs-attribute">background-color</span>: pink;
}

<span class="hljs-selector-tag">div</span> {
  <span class="hljs-attribute">padding</span>: <span class="hljs-number">20px</span>;
  <span class="hljs-attribute">background-color</span>: green;
  <span class="hljs-attribute">width</span>: max-content;
}

<span class="hljs-selector-tag">span</span> {
  <span class="hljs-attribute">display</span>: block;
  <span class="hljs-attribute">padding</span>: <span class="hljs-number">20px</span>;
  <span class="hljs-attribute">background-color</span>: blue;
}
</code></pre>
<p>The result:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/10/image-256.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>The <strong>button</strong> is a child of the <strong>span</strong>, which in turn is a child of the <strong>div</strong>, and the div is a child of the <strong>body</strong>. The DOM tree would look like this:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/10/image-263.png" alt="Image" width="600" height="400" loading="lazy">
<em>DOM tree for this interaction</em></p>
<p>When you click the <strong>button</strong>, you can think of it like you're also clicking the <strong>span</strong> (the blue background). This is because the button is a child of the span. </p>
<p>It's also the same thing with the <strong>div</strong> and the <strong>body</strong>. When you click the button, it's just like you're also clicking the span, div, and body because they are the button's ancestors. This is the idea of event bubbling.</p>
<p>An event doesn't stop at the direct element that receives it. The event bubbles up to its ancestors, until it gets to the root element.</p>
<p>So if the button receives a <strong>click</strong> event, for example, the <code>span</code>, <code>div</code>, and <code>body</code> (up until <strong>html</strong>, the root element) respectively receive that event:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/10/image-264.png" alt="Image" width="600" height="400" loading="lazy">
<em>Illustration showing how event bubbling works</em></p>
<p>Also, if you click on the blue box (span), the button doesn't receive the click event as it is not a parent or ancestor or the span. But, the div, body, and HTML would receive the event.</p>
<p>The same thing happens if you click on the div – the event is propagated to the body and html element.</p>
<h2 id="heading-how-to-handle-events-that-bubble">How to Handle Events that Bubble</h2>
<p>The "Event Bubbling" behavior makes it possible for you to handle an event in a parent element instead of the actual element that received the event.</p>
<p>The pattern of handling an event on an ancestor element is called Event Delegation. You can <a target="_blank" href="https://www.freecodecamp.org/news/event-delegation-javascript/">read more about it here</a>.</p>
<p>Let's create some event listeners and handlers:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> body = <span class="hljs-built_in">document</span>.getElementsByTagName(<span class="hljs-string">"body"</span>)[<span class="hljs-number">0</span>]
<span class="hljs-keyword">const</span> div = <span class="hljs-built_in">document</span>.getElementsByTagName(<span class="hljs-string">"div"</span>)[<span class="hljs-number">0</span>]
<span class="hljs-keyword">const</span> span = <span class="hljs-built_in">document</span>.getElementsByTagName(<span class="hljs-string">"span"</span>)[<span class="hljs-number">0</span>]
<span class="hljs-keyword">const</span> button = <span class="hljs-built_in">document</span>.getElementsByTagName(<span class="hljs-string">"button"</span>)[<span class="hljs-number">0</span>]

body.addEventListener(<span class="hljs-string">'click'</span>, <span class="hljs-function">() =&gt;</span> {
  <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"body was clicked"</span>)
})

div.addEventListener(<span class="hljs-string">'click'</span>, <span class="hljs-function">() =&gt;</span> {
  <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"div was clicked"</span>)
})

span.addEventListener(<span class="hljs-string">'click'</span>, <span class="hljs-function">() =&gt;</span> {
  <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"span was clicked"</span>)
})

button.addEventListener(<span class="hljs-string">'click'</span>, <span class="hljs-function">() =&gt;</span> {
  <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"button was clicked"</span>)
})
</code></pre>
<p>Here, we've selected the <code>body</code>, <code>div</code>, <code>span</code>, and <code>button</code> elements from the DOM. Then we added the <code>click</code> event listeners to each of them and a handler function that logs "body was clicked", "div was clicked", "span was clicked", and "button was clicked", respectively.</p>
<p>What happens on the console when you click on the pink background (which is the body) is:</p>
<pre><code class="lang-bash">body was clicked
</code></pre>
<p>When you click on the green background (which is the div), the console shows:</p>
<pre><code class="lang-bash">div was clicked
body was clicked
</code></pre>
<p>The "click" event on the body element is triggered even though the div element was the target element clicked because the "click" event bubbled from the div to the body.</p>
<p>When you click on the blue background (which is the span), the console shows:</p>
<pre><code class="lang-bash">span was clicked
div was clicked
body was clicked
</code></pre>
<p>And, lastly, when you click on the button, the console shows:</p>
<pre><code class="lang-bash">button was clicked
span was clicked
div was clicked
body was clicked
</code></pre>
<h2 id="heading-how-to-stop-event-bubbling">How to Stop Event Bubbling</h2>
<p>Event Bubbling is a default behavior for events. But in some cases, you might want to prevent this. </p>
<p>Let's say, for example, from our HTML code, that you want the div to open a modal when it is clicked. For the button, on the other hand, you want it to make an API request when it is clicked.</p>
<p>In this case, you may not want the modal to open when you click the button. You might want the modal to only open when you actually click it (and not when you click any of its children). This is where preventing event propagation comes in.</p>
<p>To prevent event bubbling, you use the <code>stopPropagation</code> method of the event object.</p>
<p>When handling events, an <code>event</code> object is passed to the handling function:</p>
<pre><code class="lang-js">button.addEventListener(<span class="hljs-string">"click"</span>, <span class="hljs-function">(<span class="hljs-params">event</span>) =&gt;</span> {
  <span class="hljs-comment">// do anything with the event object</span>
}
</code></pre>
<p>The <code>event</code> object contains properties that have information about the event that was triggered and the element it was triggered on. This object also contains methods – one of which is <code>stopPropagation()</code>.</p>
<p>The <code>stopPropagation</code> method of an event prevents the event from propagating to the parents and ancestors of the element the event was triggered on. </p>
<p>We can use this in the JavaScript code from above:</p>
<pre><code class="lang-js">body.addEventListener(<span class="hljs-string">'click'</span>, <span class="hljs-function">() =&gt;</span> {
  <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"body was clicked"</span>)
})

div.addEventListener(<span class="hljs-string">'click'</span>, <span class="hljs-function">() =&gt;</span> {
  <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"div was clicked"</span>)
})

span.addEventListener(<span class="hljs-string">'click'</span>, <span class="hljs-function">() =&gt;</span> {
  <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"span was clicked"</span>)
})

button.addEventListener(<span class="hljs-string">'click'</span>, <span class="hljs-function">(<span class="hljs-params">event</span>) =&gt;</span> {
  event.stopPropagation()
  <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"button was clicked"</span>)
})
</code></pre>
<p>With this, when you click on the button, all you get in the console is:</p>
<pre><code class="lang-bash">button was clicked
</code></pre>
<p>The button's parents and ancestors do not receive the click event as it doesn't bubble up from the button.</p>
<p>You can also stop the bubbling from a different element like this:</p>
<pre><code class="lang-js">body.addEventListener(<span class="hljs-string">'click'</span>, <span class="hljs-function">() =&gt;</span> {
  <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"body was clicked"</span>)
})

div.addEventListener(<span class="hljs-string">'click'</span>, <span class="hljs-function">() =&gt;</span> {
  <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"div was clicked"</span>)
})

span.addEventListener(<span class="hljs-string">'click'</span>, <span class="hljs-function">(<span class="hljs-params">event</span>) =&gt;</span> {
  event.stopPropagation()
  <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"span was clicked"</span>)
})

button.addEventListener(<span class="hljs-string">'click'</span>, <span class="hljs-function">() =&gt;</span> {
  <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"button was clicked"</span>)
})
</code></pre>
<p>With the <code>stopPropagation()</code> called on the span's event listener, and the button clicked, on the console you get:</p>
<pre><code class="lang-js">button was clicked
span was clicked
</code></pre>
<p>The event bubbles from the button to the span but stops there because the propagation is stopped at this point.</p>
<h2 id="heading-wrapping-up">Wrapping Up</h2>
<p>When elements receive events, such events propagate to their parents and ancestors upward in the DOM tree. This is the concept of <strong>Event Bubbling</strong>, and it allows parent elements to handle events that occur on their children's elements.</p>
<p>Event objects also have the <code>stopPropagation</code> method which you can use to stop the bubbling of an event. This is useful in cases where you want an element to receive a click event only when it is clicked and not when any of its children elements are clicked.</p>
<p><code>stopPropagation</code> and <code>preventDefault</code> are methods of the event object for stopping default behaviors. Here is an article on <a target="_blank" href="https://www.freecodecamp.org/news/manage-default-behavior-in-browser/">the difference between these methods</a>.</p>
 ]]>
                </content:encoded>
            </item>
        
    </channel>
</rss>
