<?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[ browser - 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[ browser - freeCodeCamp.org ]]>
            </title>
            <link>https://www.freecodecamp.org/news/</link>
        </image>
        <generator>Eleventy</generator>
        <lastBuildDate>Thu, 14 May 2026 22:44:05 +0000</lastBuildDate>
        <atom:link href="https://www.freecodecamp.org/news/tag/browser/rss.xml" rel="self" type="application/rss+xml" />
        <ttl>60</ttl>
        
            <item>
                <title>
                    <![CDATA[ How to Design Accessible Browser Extensions ]]>
                </title>
                <description>
                    <![CDATA[ Building a browser extension is easy, but ensuring that it’s accessible to everyone takes deliberate care and skill. Your extension might fetch data flawlessly and have a beautiful interface, but if screen reader users or keyboard navigators can’t us... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-design-accessible-browser-extensions/</link>
                <guid isPermaLink="false">68c169e7d950044818727fd6</guid>
                
                    <category>
                        <![CDATA[ browser ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Accessibility ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Browser Extension ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Browsers ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Ophy Boamah ]]>
                </dc:creator>
                <pubDate>Wed, 10 Sep 2025 12:07:03 +0000</pubDate>
                <media:content url="https://cdn.hashnode.com/res/hashnode/image/upload/v1757460414092/f3a9f3ec-f520-4627-b839-a28f15574ba6.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Building a browser extension is easy, but ensuring that it’s accessible to everyone takes deliberate care and skill.</p>
<p>Your extension might fetch data flawlessly and have a beautiful interface, but if screen reader users or keyboard navigators can’t use it, you’ve unintentionally excluded many potential users.</p>
<p>In this article, we will audit a Chrome browser extension for accessibility issues and transform it into an inclusive experience that works for everyone.</p>
<h2 id="heading-table-of-contents">Table of Contents</h2>
<ul>
<li><p><a class="post-section-overview" href="#heading-why-accessibility-matters-in-browser-extensions">Why Accessibility Matters in Browser Extensions</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-perform-manual-browser-extension-accessibility-tests">How to Perform Manual Browser Extension Accessibility Tests</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-implement-browser-extension-accessibility-improvements">How to Implement Browser Extension Accessibility Improvements</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-perform-automated-browser-extension-accessibility-tests">How to Perform Automated Browser Extension Accessibility Tests</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-best-practices-for-accessible-browser-extensions">Best Practices for Accessible Browser Extensions</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-conclusion">Conclusion</a></p>
</li>
</ul>
<h2 id="heading-why-accessibility-matters-in-browser-extensions">Why Accessibility Matters in Browser Extensions</h2>
<p>Every click in your browser extension is an opportunity to empower users or exclude them if accessibility isn’t part of your design.</p>
<p>Browser extensions face unique accessibility challenges, as they must inject functionality into existing web pages while maintaining their own accessible interfaces - a dual responsibility that can introduce potential barriers. For example, a popup that traps keyboard users or fails to communicate with screen readers can render an extension unusable.</p>
<p>With over one billion people living with disabilities, according to the World Health Organization, accessible design unlocks a vast user base and creates better experiences for everyone.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1757242166628/da2f87e2-5903-4bae-a2f4-071b2a339c69.png" alt="An infographic showing browser extension common accessibility barriers" class="image--center mx-auto" width="1022" height="426" loading="lazy"></p>
<p>For browser extensions, accessibility barriers commonly emerge as:</p>
<ul>
<li><p><strong>Keyboard navigation dead-ends</strong>: Popups and interfaces that trap or exclude keyboard users.</p>
</li>
<li><p><strong>Silent interactions</strong>: Missing labels and descriptions, like a button with only an icon announced as “unlabelled button” by screen readers, leaving users guessing about its purpose.</p>
</li>
<li><p><strong>Unannounced dynamic content updates</strong>: Content changes that occur without assistive technology awareness, such as a quote updating without notifying screen readers of the change, including missing feedback for loading states or errors</p>
</li>
<li><p><strong>Context integration conflicts</strong>: Extensions modifying existing web pages can mistakenly break the page's accessibility features or introduce elements that clash with established navigation patterns</p>
</li>
</ul>
<p>By understanding these barriers, developers can take targeted steps to test and improve their extensions’ accessibility.</p>
<h2 id="heading-how-to-perform-manual-browser-extension-accessibility-tests">How to Perform Manual Browser Extension Accessibility Tests</h2>
<p>While automated tools catch obvious issues, manual testing reveals the real user experience. Here's how to systematically evaluate your extension's accessibility.</p>
<div data-node-type="callout">
<div data-node-type="callout-emoji">💡</div>
<div data-node-type="callout-text">You can use any unpublished browser extension to follow along. For this test, we’ll be using the <a target="_self" href="https://www.freecodecamp.org/news/how-to-build-an-advice-generator-chrome-extension-with-manifest-v3/">browser extension built in this article</a>, which uses <a target="_self" href="https://www.frontendmentor.io/challenges/advice-generator-app-QdUG-13db?via=ophyboamah">this Advice generator app design</a>.</div>
</div>

<h3 id="heading-keyboard-navigation-test">Keyboard Navigation Test</h3>
<p>Disconnect your mouse and try to use your extension completely with the keyboard only. Navigate using <code>Tab</code> to move between elements, <code>Enter</code> or <code>Space</code> to activate buttons, and arrow keys within components. </p>
<ul>
<li><p>Is it always clear which element has focus?</p>
</li>
<li><p>Can you activate buttons with <code>Enter</code> or <code>Space</code> as expected?</p>
</li>
<li><p>Can users exit modal dialogs or dropdown menus?</p>
</li>
</ul>
<p>If you encounter any dead-ends or confusion points, keyboard users will face the same barriers.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1757242828152/b1555a79-a810-4d02-a995-6bf101ca2564.png" alt="An screenshot of an advice interface with a focused button " class="image--center mx-auto" width="954" height="526" loading="lazy"></p>
<h3 id="heading-screen-reader-evaluation">Screen Reader Evaluation</h3>
<p>Use your operating system's built-in screen reader to navigate your extension and listen to what is announced. On macOS, enable VoiceOver; on Windows, use Narrator; on Linux, try Orca. </p>
<ul>
<li><p>Does each element’s purpose come through clearly, such as a button announced as “Generate new advice” rather than just “button”?</p>
</li>
<li><p>Are headings, lists, and other structures properly conveyed?</p>
</li>
<li><p>Do users understand when content is loading, selected, or has changed?</p>
</li>
</ul>
<p>This testing phase often reveals the gap between what you intended to communicate and what actually reaches users.</p>
<h3 id="heading-visual-accessibility-review">Visual Accessibility Review</h3>
<p>Examine your extension in different visual contexts. Use developer tools, like WebAIM’s Contrast Checker, to verify that text meets WCAG’s 4.5:1 contrast ratio for readability. Test how your extension appears in system high-contrast settings. Ensure:</p>
<ul>
<li><p>Functionality remains usable at 200% zoom.</p>
</li>
<li><p>Information isn’t conveyed through colour alone, such as using text labels alongside colour-coded indicators.</p>
</li>
</ul>
<p>These manual tests will uncover critical accessibility issues, paving the way for targeted improvements to make your extension inclusive.</p>
<h2 id="heading-how-to-implement-browser-extension-accessibility-improvements">How to Implement Browser Extension Accessibility Improvements</h2>
<p>Imagine refreshing a page without knowing it happened or clicking a button with no clear purpose. The manual tests performed above revealed that's the experience for screen reader users of our extension among these three key accessibility issues:</p>
<ul>
<li><p><strong>Missing button label</strong>: The dice button only has an image with alt text “Dice icon,” which lacks the context screen readers need</p>
</li>
<li><p><strong>Silent dynamic updates</strong>: When new advice loads, screen readers don't know the content has changed</p>
</li>
<li><p><strong>No loading states</strong>: When fetching advice, users receive no feedback that something is happening</p>
</li>
</ul>
<p>Let's address the issues before conducting automated tests.</p>
<h3 id="heading-how-to-address-missing-button-label-and-alt-text">How to Address Missing Button Label and Alt text</h3>
<p>We’ll add <code>aria-label</code> to clearly explain the button's purpose and provide descriptive alt text for the icon. The <code>role="presentation"</code> attribute ensures the image is treated as decorative by screen readers.</p>
<pre><code class="lang-xml"><span class="hljs-comment">&lt;!--Before: Unclear Button Purpose and icon alt text--&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"dice-button"</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"generate-advice-btn"</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">img</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"/icons/icon-dice.png"</span> <span class="hljs-attr">alt</span>=<span class="hljs-string">"Dice icon"</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>

<span class="hljs-comment">&lt;!--After: Clear, Accessible Button and icon alt text--&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"dice-button"</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"generate-advice-btn"</span> <span class="hljs-attr">aria-label</span>=<span class="hljs-string">"Generate new advice"</span>&gt;</span>
     <span class="hljs-tag">&lt;<span class="hljs-name">img</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"/icons/icon-dice.png"</span> <span class="hljs-attr">alt</span>=<span class="hljs-string">"A dice icon with green background"</span> <span class="hljs-attr">role</span>=<span class="hljs-string">"presentation"</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
</code></pre>
<h3 id="heading-how-to-address-silent-dynamic-updates">How to Address Silent Dynamic Updates</h3>
<p>We’ll add <code>aria-live="polite"</code> for screen readers to announce new advice and <code>aria-atomic="true"</code> to ensure that the entire quote is read. That is:</p>
<pre><code class="lang-xml"><span class="hljs-comment">&lt;!--Before: Silent Dynamic Updates--&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">p</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"advice-quote"</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"advice-quote"</span>&gt;</span>
    "It is easy to sit up and take notice, what's difficult is getting up and taking action."
<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>

<span class="hljs-comment">&lt;!--After: Announced Content Changes--&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">p</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"advice-quote"</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"advice-quote"</span> <span class="hljs-attr">aria-live</span>=<span class="hljs-string">"polite"</span> <span class="hljs-attr">aria-atomic</span>=<span class="hljs-string">"true"</span>&gt;</span>
    "It is easy to sit up and take notice, what's difficult is getting up and taking action."
<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
</code></pre>
<h3 id="heading-how-to-address-no-loading-states">How to Address No Loading States</h3>
<p>We’ll add a <code>setLoadingState</code> function to provide loading indicators, ensuring screen reader users are notified when content is being fetched:</p>
<pre><code class="lang-javascript"><span class="hljs-comment">// Before: No Loading Feedback</span>
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">requestNewAdvice</span>(<span class="hljs-params"></span>) </span>{
  chrome.runtime.sendMessage({ <span class="hljs-attr">action</span>: <span class="hljs-string">"fetchAdvice"</span> }, <span class="hljs-function">(<span class="hljs-params">response</span>) =&gt;</span> {
    <span class="hljs-comment">// No loading indicators...</span>
  });
}

<span class="hljs-comment">// After: Accessible Loading States</span>
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">requestNewAdvice</span>(<span class="hljs-params"></span>) </span>{
  setLoadingState(<span class="hljs-literal">true</span>); 
  chrome.runtime.sendMessage({ <span class="hljs-attr">action</span>: <span class="hljs-string">"fetchAdvice"</span> }, <span class="hljs-function">(<span class="hljs-params">response</span>) =&gt;</span> {
    setLoadingState(<span class="hljs-literal">false</span>);
    <span class="hljs-comment">// Handle response with proper announcements...</span>
  });
}
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">setLoadingState</span>(<span class="hljs-params">isLoading</span>) </span>{
  <span class="hljs-keyword">if</span> (isLoading) {
    <span class="hljs-comment">// Disable button and show loading text</span>
    generateAdviceBtn.disabled = <span class="hljs-literal">true</span>;
    generateAdviceBtn.setAttribute(<span class="hljs-string">'aria-label'</span>, <span class="hljs-string">'Loading new advice...'</span>);
    <span class="hljs-comment">// Show loading text in the advice quote element</span>
    adviceQuoteElement.textContent = <span class="hljs-string">"Loading new advice..."</span>;
  } <span class="hljs-keyword">else</span> {
    <span class="hljs-comment">// Re-enable button</span>
    generateAdviceBtn.disabled = <span class="hljs-literal">false</span>;
    generateAdviceBtn.setAttribute(<span class="hljs-string">'aria-label'</span>, <span class="hljs-string">'Generate new advice'</span>);
  }
}
</code></pre>
<p>With the manual testing issues addressed, we can now move on to performing an automated test of the same extension.</p>
<h2 id="heading-how-to-perform-automated-browser-extension-accessibility-tests">How to Perform Automated Browser Extension Accessibility Tests</h2>
<p>Manual testing provides crucial insights, but automated tools can efficiently catch common issues and provide ongoing monitoring. </p>
<p>This <a target="_blank" href="https://extensiona11ychecker.vercel.app/">Extension Accessibility Checker</a> simplifies testing by analyzing browser extension interfaces, such as popups and content scripts, for WCAG compliance, addressing unique challenges like popup constraints and content injection conflicts.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1757239257443/42918662-1465-4c01-8f07-ada5d9adb174.gif" alt="A GIF showing how to test an extension zip file with the Extension accessibility checker tool" class="image--center mx-auto" width="836" height="720" loading="lazy"></p>
<p>To use the Extension Accessibility Checker:</p>
<ol>
<li><p>Compress your browser extension folder into a .zip file</p>
</li>
<li><p>Upload the .zip file on <a target="_blank" href="https://extensiona11ychecker.vercel.app/">https://extensiona11ychecker.vercel.app/</a></p>
</li>
<li><p>Review the generated report for specific accessibility violations and implement suggested fixes </p>
</li>
</ol>
<p>As shown in the GIF above, this workflow helps establish accessibility as a routine part of your development process rather than an afterthought.</p>
<p>With automated testing in place, let’s explore best practices to ensure that your extension remains accessible throughout development.</p>
<h2 id="heading-best-practices-for-accessible-browser-extensions">Best Practices for Accessible Browser Extensions</h2>
<p>We've transformed our <a target="_blank" href="https://www.frontendmentor.io/challenges/advice-generator-app-QdUG-13db?via=ophyboamah">sample advice-generating browser extension</a> from a functional but inaccessible tool into an inclusive one that works for everyone. </p>
<p>Based on our improvements, here are four key principles for designing accessible browser extensions:</p>
<ol>
<li><h3 id="heading-semantic-html-and-clear-descriptive-labels">Semantic HTML and Clear, Descriptive Labels</h3>
</li>
</ol>
<p>Always start with proper HTML structure, using appropriate elements (for example, for a “Generate Advice” action, proper heading hierarchy) before adding ARIA attributes.</p>
<p>Ensure that every interactive element has a clear purpose via <code>aria-label</code>, <code>aria-labelledby</code>, or visible text that explains its action.</p>
<ol start="2">
<li><h3 id="heading-clear-communication-at-every-step">Clear Communication at Every Step</h3>
</li>
</ol>
<p>Every interactive element must convey its purpose effectively. Users need to understand:</p>
<ul>
<li><ul>
<li><p>What’s happening (for example, “Loading new advice…” for loading states)</p>
<ul>
<li><p>What went wrong (for example, “Failed to load advice” for errors)</p>
</li>
<li><p>What changed (for example, aria-live regions for updated content)</p>
</li>
</ul>
</li>
</ul>
</li>
</ul>
<ol start="3">
<li><h3 id="heading-complete-keyboard-accessibility">Complete Keyboard Accessibility</h3>
</li>
</ol>
<p>All functionality must be available through keyboard navigation. This requires testing with <code>Tab</code>, <code>Enter</code>, <code>Space</code>, and arrow keys as appropriate.</p>
<p>Provide clear and thoughtful focus indicators that move predictably through your interface with obvious ways to exit modals or complex interactions.</p>
<ol start="4">
<li><h3 id="heading-user-preferences-and-content-script-considerations">User Preferences and Content Script Considerations</h3>
</li>
</ol>
<p>Respect user choices by supporting system font size settings and not overriding user-defined colour schemes unnecessarily.</p>
<p>When your extension modifies existing web pages, make sure you don't break the page's established accessibility features, focus management and navigation patterns. Ensure any new elements you inject follow accessibility standards.</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>As we’ve seen with our <a target="_blank" href="https://www.frontendmentor.io/challenges/advice-generator-app-QdUG-13db?via=ophyboamah">advice-generating extension</a>, addressing accessibility issues transforms a functional tool into an inclusive one.</p>
<p>However, while fixing issues in existing extensions is helpful, the most effective approach is letting accessibility guide your design and development decisions from the first line of code.</p>
<p>When starting your next browser extension project, ask:</p>
<ul>
<li><p>How would someone navigate this using only a keyboard?</p>
</li>
<li><p>Is the purpose of every interactive element immediately clear to screen readers?</p>
</li>
<li><p>How will users understand what's happening during loading states?</p>
</li>
</ul>
<p>Here are some helpful resources</p>
<ul>
<li><p><a target="_blank" href="https://developer.chrome.com/docs/extensions/mv3/a11y/">Chrome Extension Accessibility Documentation</a></p>
</li>
<li><p><a target="_blank" href="https://extensiona11ychecker.vercel.app/">Extension Accessibility Checker</a></p>
</li>
<li><p><a target="_blank" href="https://www.w3.org/WAI/WCAG21/quickref/">Web Content Accessibility Guidelines (WCAG) 2.1</a></p>
</li>
</ul>
 ]]>
                </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[ Web Storage API – How to Store Data on the Browser ]]>
                </title>
                <description>
                    <![CDATA[ The Web Storage API is a set of APIs exposed by the browser so that you can store data in the browser. The data stored in the Web Storage use the key/value pair format, and both data will be stored as strings. There are two types of storage introduce... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/web-storage-api-how-to-store-data-on-the-browser/</link>
                <guid isPermaLink="false">66bd91a827629f4c5e1893bc</guid>
                
                    <category>
                        <![CDATA[ browser ]]>
                    </category>
                
                    <category>
                        <![CDATA[ data ]]>
                    </category>
                
                    <category>
                        <![CDATA[ storage ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Web Development ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Nathan Sebhastian ]]>
                </dc:creator>
                <pubDate>Fri, 12 Jan 2024 17:43:34 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2024/01/web-storage-api-feature-image.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>The Web Storage API is a set of APIs exposed by the browser so that you can store data in the browser.</p>
<p>The data stored in the Web Storage use the key/value pair format, and both data will be stored as strings.</p>
<p>There are two types of storage introduced in the Web Storage API: Local Storage and Session Storage.</p>
<p>In this article, I’m going to show you how to use the Web Storage API and why it’s useful for web developers.</p>
<h2 id="heading-how-the-web-storage-api-works">How the Web Storage API Works</h2>
<p>The Web Storage API exposes a set of objects and methods that you can use to store data in the browser. The data you store in Web Storage is private, which means no other website can access it.</p>
<p>In Google Chrome, you can view Web Storage by opening the developer tools window and going to the Application tab as shown below:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/01/web-storage-location-1.png" alt="Image" width="600" height="400" loading="lazy">
<em>The web storage location in Google Chrome</em></p>
<p>In the picture above, you can see that the Storage menu also has other storage types like Indexed DB, Web SQL, and cookies. The Web SQL standard has been deprecated, and IndexedDB is rarely used because it’s too complex. Any data you store in IndexedDB might better be stored on the server.</p>
<p>As for cookies, it’s a more traditional mechanism of storing data that only allows you to store a maximum of 4 KB of data. By contrast, the Local Storage capacity is 10 MB and the session storage has 5 MB capacity.</p>
<p>This is why we’re going to focus only on Local Storage and Session Storage in this article.</p>
<h2 id="heading-local-storage-and-session-storage-explained">Local Storage and Session Storage Explained</h2>
<p>Local Storage and Session Storage are the two standard mechanisms supported by the Web Storage API.</p>
<p>Web storage is domain specific, meaning data stored under one domain (netflix.com) can’t be accessed by another domain (www.netflix.com or members.netflix.com)</p>
<p>Web storage is also protocol specific. This means the data you store in a <code>http://</code> site won’t be available under the <code>https://</code> site.</p>
<p>The main difference between Local and Session Storage is that Local Storage will store your data forever. If you want to remove the data, you need to use the available method or clear it manually from the Applications tab.</p>
<p>By contrast, the data stored in session storage is only available during the page session. When you close the browser or the tab, the session storage for that specific tab is removed.</p>
<p>Both Local and Session Storage can be accessed through the <code>window</code> object under the variables <code>localStorage</code> and <code>sesionStorage</code>, respectively. Let’s see the methods and properties of these storage types next.</p>
<h3 id="heading-methods-and-properties-of-local-and-session-storage">Methods and Properties of Local and Session Storage</h3>
<p>Both Local and Session Storage have the same methods and properties. To set a new key/value pair in the Local Storage, you can use the <code>setItem()</code> method of the <code>localStorage</code> object:</p>
<pre><code class="lang-js"><span class="hljs-built_in">localStorage</span>.setItem(<span class="hljs-string">'firstName'</span>, <span class="hljs-string">'Nathan'</span>);
</code></pre>
<p>If you look into the Local Storage menu in the browser, you should see the data above saved into the storage as follows:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/01/localstorage-setitem.png" alt="Image" width="600" height="400" loading="lazy">
<em>Storing a key/value pair in Local Storage</em></p>
<p>The key you used in <code>localStorage</code> must be unique. If you set another data with a key that already exists, then the <code>setItem()</code> method will replace the previous value with the new one.</p>
<p>To get the value out of local storage, you need to call the <code>getItem()</code> method and pass the key you used when saving the data. If the key doesn’t exist, then <code>getItem()</code> will return <code>null</code> back:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> firstName = <span class="hljs-built_in">localStorage</span>.getItem(<span class="hljs-string">'firstName'</span>);
<span class="hljs-built_in">console</span>.log(firstName); <span class="hljs-comment">// Nathan</span>

<span class="hljs-keyword">const</span> lastName = <span class="hljs-built_in">localStorage</span>.getItem(<span class="hljs-string">'lastName'</span>);
<span class="hljs-built_in">console</span>.log(lastName); <span class="hljs-comment">// null</span>
</code></pre>
<p>To remove the data you have in local storage, call the <code>removeItem()</code> method and pass the key pointing to the data you want to remove:</p>
<pre><code class="lang-js"><span class="hljs-built_in">localStorage</span>.removeItem(<span class="hljs-string">'firstName'</span>);
</code></pre>
<p>The <code>removeItem()</code> method will always return <code>undefined</code>. When the data you want to remove doesn’t exist, the method simply does nothing.</p>
<p>If you want to clear the storage, you can use the <code>clear()</code> method:</p>
<pre><code class="lang-js"><span class="hljs-built_in">localStorage</span>.clear();
</code></pre>
<p>The <code>clear()</code> method removes all key/value pairs from the storage object you are accessing.</p>
<h3 id="heading-properties-of-local-and-session-storage">Properties of Local and Session Storage</h3>
<p>Both storage types have only one property, which is the <code>length</code> property that shows the amount of data stored in them.</p>
<pre><code class="lang-js">sessionStorage.setItem(<span class="hljs-string">'firstName'</span>, <span class="hljs-string">'Nathan'</span>);
sessionStorage.setItem(<span class="hljs-string">'lastName'</span>, <span class="hljs-string">'Sebhastian'</span>);

<span class="hljs-built_in">console</span>.log(sessionStorage.length); <span class="hljs-comment">// 2</span>

sessionStorage.clear();
<span class="hljs-built_in">console</span>.log(sessionStorage.length); <span class="hljs-comment">// 0</span>
</code></pre>
<p>And that’s all the methods and properties you can access in <code>localStorage</code> and <code>sessionStorage</code>.</p>
<h2 id="heading-how-to-store-json-strings-in-web-storage-storage">How to Store JSON Strings in Web Storage Storage</h2>
<p>Since Web Storage always stores data as strings, you can store complex data as a JSON string, and then convert that string back into an object when you access it.</p>
<p>For example, suppose I want to store the following information about a user:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> user = {
  <span class="hljs-attr">firstName</span>: <span class="hljs-string">'Nathan'</span>,
  <span class="hljs-attr">lastName</span>: <span class="hljs-string">'Sebhastian'</span>,
  <span class="hljs-attr">url</span>: <span class="hljs-string">'https://codewithnathan.com'</span>,
};
</code></pre>
<p>At first, I might store the data as a series of key/value pairs like this:</p>
<pre><code class="lang-js"><span class="hljs-built_in">localStorage</span>.setItem(<span class="hljs-string">'firstName'</span>, user.firstName);
<span class="hljs-built_in">localStorage</span>.setItem(<span class="hljs-string">'lastName'</span>, user.lastName);
<span class="hljs-built_in">localStorage</span>.setItem(<span class="hljs-string">'url'</span>, user.url);
</code></pre>
<p>But a better way is to convert the JavaScript object into a JSON string, and then store the data under one key as follows:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> user = {
  <span class="hljs-attr">firstName</span>: <span class="hljs-string">'Nathan'</span>,
  <span class="hljs-attr">lastName</span>: <span class="hljs-string">'Sebhastian'</span>,
  <span class="hljs-attr">url</span>: <span class="hljs-string">'https://codewithnathan.com'</span>,
};

<span class="hljs-keyword">const</span> userData = <span class="hljs-built_in">JSON</span>.stringify(user);

<span class="hljs-built_in">localStorage</span>.setItem(<span class="hljs-string">'user'</span>, userData);
</code></pre>
<p>Now the local storage will have only one key/value pair with the JSON string as its value. You can open the Applications tab to see this:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/01/store-as-json.png" alt="Image" width="600" height="400" loading="lazy">
<em>Storing a JSON string in Local Storage</em></p>
<p>When you need the data, call the <code>getItem()</code> and <code>JSON.parse()</code> methods as follows:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> getUser = <span class="hljs-built_in">JSON</span>.parse(<span class="hljs-built_in">localStorage</span>.getItem(<span class="hljs-string">'user'</span>));

<span class="hljs-built_in">console</span>.log(getUser);
<span class="hljs-comment">// {firstName: 'Nathan', lastName: 'Sebhastian', url: 'https://codewithnathan.com'}</span>
</code></pre>
<p>Here, you can see that the data is returned as a regular JavaScript object.</p>
<h2 id="heading-local-storage-vs-session-storage-which-one-to-use">Local Storage vs Session Storage – Which One to Use?</h2>
<p>Based on my experience, <code>localStorage</code> is the preferred Web Storage mechanism because the data will persist as long as you need it to. When you don’t need the data, you can remove it using the <code>removeItem()</code> method.</p>
<p><code>sessionStorage</code> is only used when you need to store temporary data, like tracking whether a popup box has been shown to the user or not.</p>
<p>But this is also open to discussion because you might not want to show a popup every time the user logs into your web application, but only once. In that case, you should use <code>localStorage</code> instead.</p>
<p>My rule of thumb is to use <code>localStorage</code> first, and <code>sessionStorage</code> when the situation needs it.</p>
<h2 id="heading-benefits-of-using-the-web-storage-api">Benefits of Using the Web Storage API</h2>
<p>Now that you know how the Web Storage API works, you can see that there are some benefits of using it:</p>
<ol>
<li>Storing data on the browser reduces the need to make a server request for a piece of information. This can improve the performance of your web applications.</li>
<li>The simple key/value pair format allows you to store user preferences and local settings that should persist between sessions.</li>
<li>The Web Storage API is simple to use, providing only a few methods and one property. It’s simple to set and retrieve data using JavaScript</li>
<li>It has offline support. By storing necessary data locally, the Web Storage enables your web application to work offline.</li>
<li>The Web Storage is also a standardized API, meaning the code you write will work in many different browsers.</li>
</ol>
<p>But of course, not all data should be stored in the Web Storage API. You still need a server database to keep records that are important for your application.</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>Web Storage is a useful API that allows you to quickly store and retrieve data from the browser. Using Web Storage, you can store the user’s preferences when accessing your application.</p>
<p><code>localStorage</code> allows you to store data forever until it’s removed manually, while <code>sessionStorage</code> will persist as long as the browser or tab is open.</p>
<p>Some benefits of using the Web Storage API include reducing server requests, offline support, and a simple API that’s easy to use. It’s also standardized, so it will work on different browsers.</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>See you later!  </p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Your Connection is Not Private Error – How to Fix in Chrome ]]>
                </title>
                <description>
                    <![CDATA[ If you log on to a website and your browser shows the “Your connection is not private” error, the browser is trying to warn you to stay off the website. In that case, the browser has run a check on the SSL (secure socket layer) certificate and found... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/your-connection-is-not-private-error-how-to-fix-in-chrome/</link>
                <guid isPermaLink="false">66adf297f452caf50fb1fe2b</guid>
                
                    <category>
                        <![CDATA[ browser ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Google Chrome ]]>
                    </category>
                
                    <category>
                        <![CDATA[ privacy ]]>
                    </category>
                
                    <category>
                        <![CDATA[ SSL ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Kolade Chris ]]>
                </dc:creator>
                <pubDate>Thu, 07 Jul 2022 16:03:17 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2022/07/castle-1290860_1280.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>If you log on to a website and your browser shows the “Your connection is not private” error, the browser is trying to warn you to stay off the website.
<img src="https://www.freecodecamp.org/news/content/images/2022/07/Annotation-2022-07-06-111823-1.png" alt="Annotation-2022-07-06-111823-1" width="600" height="400" loading="lazy"></p>
<p>In that case, the browser has run a check on the SSL (secure socket layer) certificate and found a problem with it – the SSL could have expired or might not have been installed at all.</p>
<p>In some cases, the problem could be because of your browser and not the website. So, in this article, I will show you how to fix the “Your connection is not private” error on a Chrome browser.</p>
<h2 id="heading-what-well-cover">What We'll Cover</h2>
<ul>
<li><a class="post-section-overview" href="#heading-how-to-fix-the-your-connection-is-not-private-error-on-a-chrome-browser">How to Fix the “Your connection is not private” Error on a Chrome Browser</a><ul>
<li><a class="post-section-overview" href="#heading-reload-the-web-page">Reload the Web Page</a> </li>
<li><a class="post-section-overview" href="#heading-clear-chromes-cache">Clear Chrome’s Cache</a></li>
<li><a class="post-section-overview" href="#heading-make-sure-your-computers-date-and-time-are-correct">Make Sure your Computer’s Date and Time are Correct</a></li>
<li><a class="post-section-overview" href="#heading-disable-your-antivirus-and-vpn">Disable your Antivirus and VPN</a></li>
</ul>
</li>
<li><a class="post-section-overview" href="#heading-final-thoughts">Final Thoughts</a></li>
</ul>
<h2 id="heading-how-to-fix-the-your-connection-is-not-private-error-on-a-chrome-browser">How to Fix the “Your connection is not private” Error on a Chrome Browser</h2>
<h3 id="heading-reload-the-web-page">Reload the Web Page</h3>
<p>The first thing I would advise you do is to reload the page.</p>
<p>Reloading the web page is the old trick everyone tries if there is a problem with that web page. </p>
<p>In addition, there are chances that SSL-related work is going on with the website, so if you wait a while and reload the page, the issue could disappear.</p>
<p>If reloading doesn’t fix the issue for you, proceed to other solutions in this article.</p>
<h3 id="heading-clear-chromes-cache">Clear Chrome’s Cache</h3>
<p>The SSL data of the website in your Chrome browser cache might have expired. So if you clear the cache, the error may go away.</p>
<p>Follow the steps below to clear your Chrome browser cache:</p>
<p><strong>Step 1</strong>: Click the 3 vertical dots on the top-right corner and select Settings:
<img src="https://www.freecodecamp.org/news/content/images/2022/07/ss10-1.png" alt="ss10-1" width="600" height="400" loading="lazy"></p>
<p><strong>Step 2</strong>: Click the “Privacy and Security” tab on the left sidebar and select “Clear browsing data”:
<img src="https://www.freecodecamp.org/news/content/images/2022/07/ss11-1.png" alt="ss11-1" width="600" height="400" loading="lazy"></p>
<p><strong>Step 3</strong>: Select Cache and Cookies, then click “Clear data”:
<img src="https://www.freecodecamp.org/news/content/images/2022/07/ss12-1.png" alt="ss12-1" width="600" height="400" loading="lazy"></p>
<h3 id="heading-make-sure-your-computers-date-and-time-are-correct">Make Sure your Computer’s Date and Time are Correct</h3>
<p>If your computer clock is behind or ahead, your browser will show you a “Your connection is not secure” error.</p>
<p>These days, the error message has become more accurate in Chrome:
<img src="https://www.freecodecamp.org/news/content/images/2022/07/Annotation-2022-06-06-072807.png" alt="Annotation-2022-06-06-072807" width="600" height="400" loading="lazy"></p>
<p>In this case, you should set your date and time to the correct one and make it automatic, so nothing readjusts it again:
<img src="https://www.freecodecamp.org/news/content/images/2022/07/ss.png" alt="ss" width="600" height="400" loading="lazy"></p>
<h3 id="heading-disable-your-antivirus-and-vpn">Disable your Antivirus and VPN</h3>
<p>Some Antivirus programs with SSL scanning features can make your browser show the “Your connection is not private” error if they detect any irregularity with the SSL certificate of a website.</p>
<p>In the same vein, a VPN (virtual private network) conceals your IP address and other information. The problem is that the privacy a VPN gives you could have a negative effect on some sites' SSL.</p>
<p>Due to this, you should consider disabling your antivirus and VPN programs, at least temporarily, to see if that fixes the error.</p>
<h2 id="heading-final-thoughts">Final Thoughts</h2>
<p>Other fixes that might get rid of the “Your connection is not private” error for you include:</p>
<ul>
<li>Trying to access the web page in incognito mode. In Chrome, you can open an incognito tab by pressing <code>CTRL</code> + <code>SHIFT</code> + <code>N</code>.</li>
<li>Restarting your Router</li>
<li>Restarting your computer</li>
<li>Updating your OS</li>
</ul>
<p>If all the fixes fail to work, the problem could be from the website. This means there is a problem with the website’s SSL certificate. So, try to contact the site admin. </p>
<p>If you find no admin to contact, you should stay off that website and make sure you don’t share sensitive information with the site.</p>
<p>If you’re a site admin and your users complain about this error, I wrote <a target="_blank" href="https://www.freecodecamp.org/news/an-ssl-error-has-occurred-how-to-fix-certificate-verification-error/#howtofixsslerrorasasiteowner">an article on how you can restore your site’s SSL</a>.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ What is the Correct Content-Type for JSON? Request Header Mime Type Explained ]]>
                </title>
                <description>
                    <![CDATA[ By Dillion Megida Every resource used on the internet has a media type, also known as a MIME type which stands for Multipurpose Internet Mail Extension. This information is necessary for transactions between server and client. The browser needs to kn... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/what-is-the-correct-content-type-for-json-request-header-mime-type-explained/</link>
                <guid isPermaLink="false">66d84f715a0b456f4d321469</guid>
                
                    <category>
                        <![CDATA[ browser ]]>
                    </category>
                
                    <category>
                        <![CDATA[ internet ]]>
                    </category>
                
                    <category>
                        <![CDATA[ json ]]>
                    </category>
                
                    <category>
                        <![CDATA[ servers ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Tue, 08 Dec 2020 22:07:17 +0000</pubDate>
                <media:content url="https://cdn-media-2.freecodecamp.org/w1280/5fcf4739e6787e098393bd6d.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Dillion Megida</p>
<p>Every resource used on the internet has a media type, also known as a MIME type which stands for Multipurpose Internet Mail Extension. This information is necessary for transactions between server and client.</p>
<p>The browser needs to know the media type of resources sent to it so that it can handle them properly.</p>
<p>The same goes for the server. It needs to know the type of resources sent to it for accurate parsing and processing.</p>
<h2 id="heading-where-is-the-content-type-declared">Where is the Content-Type declared?</h2>
<p>The media type of any resource is declared in the <code>Content-Type</code> property of the request header (on the client, when making a request to the server) or in the response header (on the server, when sending a response).</p>
<p>Without explicitly declaring the content type of a resource, the client may attempt to automatically detect the type, but the result may not be accurate. This is why it's important to explicitly declare it.</p>
<h2 id="heading-media-types">Media Types</h2>
<p>Media types exist in various forms. They are categorized into various groups:</p>
<ul>
<li>application</li>
<li>audio</li>
<li>font</li>
<li>example</li>
<li>image</li>
<li>message</li>
<li>model</li>
<li>multipart</li>
<li>text</li>
<li>and video</li>
</ul>
<p>These categories also have their types. For example, <code>application/json</code> is a type under <code>application</code> and <code>text/html</code> is a type under <code>text</code>.</p>
<p>You can find a complete list of media types in the <a target="_blank" href="https://www.iana.org/assignments/media-types/media-types.xhtml">IANA</a> (a body that coordinates some of the key elements on the internet) media types.</p>
<p>All these types cover various data types like text, audio, images, HTML, and many more types that are used across the internet.</p>
<h2 id="heading-the-browser-needs-to-know-the-media-type-of-a-resource">The browser needs to know the media type of a resource</h2>
<p>As I mentioned above, the browser needs to know what type of content it receives. Here's an example to illustrate that.</p>
<p>The following code is a Node server that serves an HTML file:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> http = <span class="hljs-built_in">require</span>(<span class="hljs-string">"http"</span>);
<span class="hljs-keyword">const</span> fs = <span class="hljs-built_in">require</span>(<span class="hljs-string">"fs"</span>);
<span class="hljs-keyword">const</span> path = <span class="hljs-built_in">require</span>(<span class="hljs-string">"path"</span>);

<span class="hljs-keyword">const</span> server = http.createServer(<span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">req, res</span>) </span>{
    <span class="hljs-keyword">const</span> filePath = path.join(__dirname, <span class="hljs-string">"index.html"</span>);
    <span class="hljs-keyword">var</span> stat = fs.statSync(filePath);

    res.writeHead(<span class="hljs-number">200</span>, {
        <span class="hljs-string">"Content-Type"</span>: <span class="hljs-string">"text/css"</span>,
        <span class="hljs-string">"Content-Length"</span>: stat.size,
    });

    <span class="hljs-keyword">const</span> readStream = fs.createReadStream(filePath);
    readStream.pipe(res);
});

server.listen(<span class="hljs-number">5000</span>);

<span class="hljs-built_in">console</span>.log(<span class="hljs-string">"Node.js web server at port 5000 is running.."</span>);
</code></pre>
<p>Do not worry about the specifics of the code. All you're concerned with is the <code>index.htm</code> file we're serving and that the <code>Content-Type</code> is <code>text/css</code>.</p>
<p>Here's the content of <code>index.html</code>:</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">h1</span>&gt;</span>Homepage<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span>
</code></pre>
<p>Of course, an HTML document is different from a  CSS file. Here's the result on <code>localhost:5000</code> when the server is started:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/12/Screenshot-2020-12-08-at-10.12.32.png" alt="Screenshot-2020-12-08-at-10.12.32" width="600" height="400" loading="lazy"></p>
<p>You can also confirm the response gotten by checking the headers in the network tab of the DevTools.</p>
<p>Here's the result on a Chrome browser:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/12/Screenshot-2020-12-08-at-10.13.34.png" alt="Screenshot-2020-12-08-at-10.13.34" width="600" height="400" loading="lazy"></p>
<p>The browser got the content as a CSS type, therefore, it tried treating it as CSS.</p>
<p>Also, note that full knowledge of the type of content gotten by the browser also reduces security vulnerabilities as the browser knows security standards to put in place for that data.</p>
<p>Now that you understand the concept of MIME types and their importance, let's head over to JSON.</p>
<h2 id="heading-the-correct-content-type-for-json">The Correct Content-Type for JSON</h2>
<p>JSON has to be correctly interpreted by the browser to be used appropriately. <code>text/plain</code> was typically used for JSON, but according to <a target="_blank" href="https://www.iana.org/assignments/media-types/media-types.xhtml">IANA</a>, the official MIME type for JSON is <code>application/json</code>.</p>
<p>This means when you're sending JSON to the server or receiving JSON from the server, you should always declare the <code>Content-Type</code> of the header as <code>application/json</code> as this is the standard that the client and server understand.</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>As stated above, the server (just like the browser) needs to know the type of data sent to it, say, in a POST request. That's the reason <code>forms</code> with files usually contain the <code>enctype</code> attribute with a value of <code>multipart/form-data</code>. </p>
<p>Without encoding the request this way, the POST request won't work. Also, once the server knows the type of data it has gotten, it then knows how to parse the encoded data.</p>
<p>In this article, we looked at what MIME types are and their purpose. Also, we looked at the official content type for JSON. I hope you now know why it's important to declare resource types when used across the internet.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ JavaScript URL Encode Example – How to Use encodeURIcomponent() and encodeURI() ]]>
                </title>
                <description>
                    <![CDATA[ You might think that encodeURI and encodeURIComponent do the same thing, at least from their names. And you might be confused which one to use and when. In this article, I will demystify the difference between encodeURI and encodeURIComponent.  What ... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/javascript-url-encode-example-how-to-use-encodeuricomponent-and-encodeuri/</link>
                <guid isPermaLink="false">66b99cf7489480391dfe7a4a</guid>
                
                    <category>
                        <![CDATA[ browser ]]>
                    </category>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Shruti Kapoor ]]>
                </dc:creator>
                <pubDate>Tue, 04 Aug 2020 22:39:13 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2020/08/richy-great-MAYEkmn7G6E-unsplash.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>You might think that <code>encodeURI</code> and <code>encodeURIComponent</code> do the same thing, at least from their names. And you might be confused which one to use and when.</p>
<p>In this article, I will demystify the difference between <code>encodeURI</code> and <code>encodeURIComponent</code>. </p>
<h3 id="heading-what-is-a-uri-and-how-is-it-different-from-a-url">What is a URI and how is it different from a URL?</h3>
<p><strong>URI</strong> stands for Uniform Resource Identifier.
<strong>URL</strong> stands for Uniform Resource Locator.</p>
<p>Anything that uniquely identifies a resource is its URI, such as id, name, or ISBN number. A URL specifies a resource and how it can be accessed (the protocol).  All URLs are URIs, but not all URIs are URLs.</p>
<h3 id="heading-why-do-we-need-to-encode">Why do we need to encode?</h3>
<p>URLs can only have certain characters from the standard 128 character ASCII set. Reserved characters that do not belong to this set must be encoded. </p>
<p>This means that we need to encode these characters when passing into a URL. Special characters such as <code>&amp;</code>, <code>space</code>, <code>!</code> when entered in a url need to be escaped, otherwise they may cause unpredictable situations. </p>
<p>Use cases:</p>
<ol>
<li>User has submitted values in a form that may be in a string format and need to be passed in, such as URL fields. </li>
<li>Need to accept query string parameters in order to make GET requests.</li>
</ol>
<h3 id="heading-what-is-the-difference-between-encodeuri-and-encodeuricomponent">What is the difference between encodeURI and encodeURIComponent?</h3>
<p><code>encodeURI</code> and <code>encodeURIComponent</code> are used to encode Uniform Resource Identifiers (URIs) by replacing certain characters by one, two, three or four escape sequences representing the UTF-8 encoding of the character.</p>
<p><code>encodeURIComponent</code> should be used to encode a <strong>URI</strong> <strong>Component</strong> - a string that is supposed to be part of a URL.</p>
<p><code>encodeURI</code> should be used to encode a <strong>URI</strong> or an existing URL. </p>
<p><a target="_blank" href="https://stackoverflow.com/a/23842171">Here's a handy table of the difference in encoding of characters</a></p>
<h3 id="heading-which-characters-are-encoded">Which characters are encoded?</h3>
<p><code>encodeURI()</code> will not encode: <code>~!@#$&amp;*()=:/,;?+'</code></p>
<p><code>encodeURIComponent()</code> will not encode: <code>~!*()'</code></p>
<p>The characters <code>A-Z a-z 0-9 - _ . ! ~ * ' ( )</code> are not escaped. </p>
<h3 id="heading-examples">Examples</h3>
<pre><code class="lang-JS"><span class="hljs-keyword">const</span> url = <span class="hljs-string">'https://www.twitter.com'</span>

<span class="hljs-built_in">console</span>.log(<span class="hljs-built_in">encodeURI</span>(url))             <span class="hljs-comment">//https://www.twitter.com</span>
<span class="hljs-built_in">console</span>.log(<span class="hljs-built_in">encodeURIComponent</span>(url))    <span class="hljs-comment">//https%3A%2F%2Fwww.twitter.com</span>


<span class="hljs-keyword">const</span> paramComponent = <span class="hljs-string">'?q=search'</span>
<span class="hljs-built_in">console</span>.log(<span class="hljs-built_in">encodeURIComponent</span>(paramComponent)) <span class="hljs-comment">//"%3Fq%3Dsearch"</span>
<span class="hljs-built_in">console</span>.log(url + <span class="hljs-built_in">encodeURIComponent</span>(paramComponent)) <span class="hljs-comment">//https://www.twitter.com%3Fq%3Dsearch</span>
</code></pre>
<h3 id="heading-when-to-encode">When to encode</h3>
<ol>
<li>When accepting an input that may have spaces.<pre><code class="lang-JS"> <span class="hljs-built_in">encodeURI</span>(<span class="hljs-string">"http://www.mysite.com/a file with spaces.html"</span>) <span class="hljs-comment">//http://www.mysite.com/a%20file%20with%20spaces.html</span>
</code></pre>
</li>
<li><p>When building a URL from query string parameters.</p>
<pre><code class="lang-JS"> <span class="hljs-keyword">let</span> param = <span class="hljs-built_in">encodeURIComponent</span>(<span class="hljs-string">'mango'</span>)
 <span class="hljs-keyword">let</span> url = <span class="hljs-string">"http://mysite.com/?search="</span> + param + <span class="hljs-string">"&amp;length=99"</span>; <span class="hljs-comment">//http://mysite.com/?search=mango&amp;length=99</span>
</code></pre>
</li>
<li><p>When accepting query parameters that may have reserved characters.
```JS
 let params = encodeURIComponent('mango &amp; pineapple')
 let url = "http://mysite.com/?search=" + params; //http://mysite.com/?search=mango%20%26%20pineapple</p>
</li>
</ol>
<p>   ```</p>
<h3 id="heading-summary">Summary</h3>
<p>If you have a complete URL, use <code>encodeURI</code>. But if you have a part of a URL, use <code>encodeURIComponent</code>. </p>
<hr>
<p>Interested in more tutorials and JSBytes from me? <a target="_blank" href="https://tinyletter.com/shrutikapoor">Sign up for my newsletter.</a> or <a target="_blank" href="https://twitter.com/shrutikapoor08">follow me on Twitter</a></p>
<p>### </p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Use HAR Files to Analyze Performance Over Time ]]>
                </title>
                <description>
                    <![CDATA[ By Leonardo Faria When I consider the performance of a website, several things come to mind. I think about looking at the requests of a page, understanding what resources are being loaded, and how long these resources take to be available to users. ... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/using-har-files-to-analyze-performance-over-time/</link>
                <guid isPermaLink="false">66d8518562a291dea89878da</guid>
                
                    <category>
                        <![CDATA[ browser ]]>
                    </category>
                
                    <category>
                        <![CDATA[ performance ]]>
                    </category>
                
                    <category>
                        <![CDATA[ web performance ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Mon, 08 Jun 2020 13:00:00 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2020/06/william-daigneault-oWrZoAVOBS0-unsplash.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Leonardo Faria</p>
<p>When I consider the performance of a website, several things come to mind. I think about looking at the requests of a page, understanding what resources are being loaded, and how long these resources take to be available to users.</p>
<p><img src="https://leonardofaria.net/wp-content/uploads/2020/06/chrome-network.jpg" alt="Chrome Network tab" width="600" height="400" loading="lazy"></p>
<p>The network tab will give you a table containing all assets loaded on the page. It will also show you relevant information about the origin of those assets (domain, HTTP status code, size), who initiated the request, and the order in which they were loaded in a waterfall representation. </p>
<p>You can add more information to this table by right-clicking one of the table headers and choosing other columns.</p>
<p>The size, time and waterfall columns will be crucial to understanding the performance of a page. The size value will present the gzipped size of the resource (when applicable), while the time column shows the total duration from the start of the request to the receipt of the final byte in the response. </p>
<p>Last, but not least, the waterfall column demonstrates when the asset is loaded along with the other requests.</p>
<p>Performance improvements are noticeable by changes in your code/environment. So how do we keep track of what is being analyzed by the Network tab? By exporting the page in HAR format.</p>
<h2 id="heading-what-is-a-har-file">What is a HAR file?</h2>
<p>A HAR (short for HTTP Archive) file is a JSON file containing all information about a browser’s interactions with a page. It will contain the HTML document and its respective JS and CSS files. </p>
<p>Along with this content, a HAR file will also contain all headers’ information and the browser metadata (that is, the time of each request).</p>
<p>It is important to mention here that cookies and form data will also be logged in the file, so be careful to not include sensitive information (personal details, passwords, credit card numbers) while auditing pages. </p>
<p>Also, you should audit pages in private windows, which avoids browser extensions. It's important to avoid a browser’s extensions since they may modify the loading times of a page.</p>
<h2 id="heading-generating-har-files">Generating HAR files</h2>
<h3 id="heading-google-chrome">Google Chrome</h3>
<ul>
<li>Close all incognito windows in Google Chrome.</li>
<li>Open a new incognito window in Google Chrome.</li>
<li>Go to View &gt; Developer &gt; Developers Tools.</li>
<li>In the Developer Tools panel, choose the Network tab.</li>
<li>Check the Preserve Log and Disable cache checkboxes to record all interactions.</li>
<li>Refresh the page.</li>
<li>Click the Export HAR (down arrow icon) to export the HAR file.</li>
<li>Save the HAR file.</li>
</ul>
<h3 id="heading-firefox">Firefox</h3>
<ul>
<li>Close all private windows in Firefox.</li>
<li>Open a new private window in Firefox.</li>
<li>Go to Tools &gt; Developer &gt; Network or ctrl-shift-E.</li>
<li>Refresh the page.</li>
<li>In the Cog icon (upper right side of the page), choose Save All As Har.</li>
<li>Save the HAR file.</li>
</ul>
<p><img src="https://leonardofaria.net/wp-content/uploads/2020/06/firefox-network.jpg" alt="Firefox Network tab" width="600" height="400" loading="lazy"></p>
<h3 id="heading-safari">Safari</h3>
<ul>
<li>Ensure that Show Develop menu in menu bar checkbox is checked under Safari &gt; Preferences &gt; Advanced.</li>
<li>Choose File &gt; Open New Private Window.</li>
<li>Visit the web page where the issue occurs.</li>
<li>Choose Develop &gt; Show Web Inspector. The Web Inspector window appears.</li>
<li>Refresh the page.</li>
<li>Click Export on the upper right side of the pane.</li>
<li>Save the HAR file.</li>
</ul>
<p><img src="https://leonardofaria.net/wp-content/uploads/2020/06/safari-network.jpg" alt="Safari Network tab" width="600" height="400" loading="lazy"></p>
<h2 id="heading-reading-har-files">Reading HAR files</h2>
<p>Once you have a HAR file, you can try a few HAR viewers online. My personal favourite is the <a target="_blank" href="http://www.softwareishard.com/har/viewer/">one created by Jan Odavarko</a>.</p>
<p><img src="https://leonardofaria.net/wp-content/uploads/2020/06/har-viewer.jpg" alt="HAR Viewer" width="600" height="400" loading="lazy"></p>
<p>What I like about this viewer in particular is the fact you can have multiple files open at the same time, which makes it easier to compare them.</p>
<h2 id="heading-using-har-files-to-analyze-the-performance-of-a-page">Using HAR files to analyze the performance of a page</h2>
<p>HAR files can be useful to collect information about the assets of a page. Since you have detailed information about their content, you can compare what has improved (or in some cases, not improved) after a new feature is launched or a redesign is completed, for example. </p>
<p>During my workflow, I like to keep track of the final size/time values of a few pages of the product that I am working on.</p>
<h2 id="heading-more-information">More information</h2>
<ul>
<li><a target="_blank" href="https://developers.google.com/web/tools/chrome-devtools/network/resource-loading#view-network-timing-details-for-a-specific-resource">Measure Resource Loading Times</a></li>
<li><a target="_blank" href="https://github.com/janodvarko/harviewer">HAR Viewer source code</a></li>
</ul>
<p>Also posted on <a target="_blank" href="https://bit.ly/2zbBPud">my blog</a>. If you like this content, follow me on <a target="_blank" href="https://twitter.com/leozera">Twitter</a> and <a target="_blank" href="https://github.com/leonardofaria">GitHub</a>. Cover photo by <a target="_blank" href="https://unsplash.com/photos/oWrZoAVOBS0">William Daigneault/Unsplash</a></p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Chrome DevTools: How to Filter Network Requests ]]>
                </title>
                <description>
                    <![CDATA[ By Adeel Imran As front end developers, most of our time is spent in the browser with DevTools open (almost always, unless we are watching YouTube ... sometimes even then).  One of the major sections in DevTools is the network tab. There are a couple... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/chrome-devtools-network-tab-tricks/</link>
                <guid isPermaLink="false">66d45d59bd438296f45cd36d</guid>
                
                    <category>
                        <![CDATA[ browser ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Google Chrome ]]>
                    </category>
                
                    <category>
                        <![CDATA[ tips ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Tue, 02 Jun 2020 21:26:48 +0000</pubDate>
                <media:content url="https://cdn-media-2.freecodecamp.org/w1280/5f9c9a87740569d1a4ca2629.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Adeel Imran</p>
<p>As front end developers, most of our time is spent in the browser with DevTools open (almost always, unless we are watching YouTube ... sometimes even then). </p>
<p>One of the major sections in DevTools is the <code>network</code> tab. There are a couple of things you can do in the <code>network</code> tab, like the following:</p>
<ul>
<li>Find network requests by text</li>
<li>Find network requests by regex expression</li>
<li>Filter (exclude) out network requests</li>
<li>Use the property filter to see network requests by a certain domain</li>
<li>Find network requests by resource type</li>
</ul>
<p>For the purposes of this tutorial I am using <a target="_blank" href="https://www.freecodecamp.org/news/">freeCodeCamp's</a> home page, <strong><a target="_blank" href="https://www.freecodecamp.org/news/">freecodecamp.org/news</a></strong>. Simply go to the page and open the <code>network</code> tab.</p>
<p>You can see the <code>network</code> tab by hitting <code>cmd + opt + j</code> on your Mac or <code>ctrl + shift + j</code> in Windows. It will open up the <code>console</code> tab in DevTools by default.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/06/Screenshot-2020-06-02-at-22.18.37.png" alt="Image" width="600" height="400" loading="lazy">
<em>Clicking "cmd + opt + j" opens up console panel in DevTools</em></p>
<p>Once the <code>console</code> tab is open, simply click on the <code>network</code> tab to make it visible.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/06/Screenshot-2020-06-02-at-22.19.57.png" alt="Image" width="600" height="400" loading="lazy">
<em>Clicking on the "network" tab will show you all network requests being made for a certain page</em></p>
<p>Once the <code>network</code> tab is open we can begin our tutorial.</p>
<h2 id="heading-lets-begin">Let's begin</h2>
<p>Make sure the correct page is open (<a target="_blank" href="https://www.freecodecamp.org/news/">freecodecamp.org/news</a>) and the "network" tab panel is open in DevTools:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/06/Screenshot-2020-06-02-at-23.12.01.png" alt="Image" width="600" height="400" loading="lazy">
<em>Illustration on where the filter bar is in network panel.</em></p>
<ul>
<li>The green box here illustrates the icon that can hide/show the filter area in the network panel tab.</li>
<li>The red box here illustrates the filter area box. With this box we can filter out network requests.</li>
</ul>
<h3 id="heading-find-network-request-by-text">Find network request by text</h3>
<p>Type <code>analytics</code> into the Filter text box. Only the files that contain the text <code>analytics</code> are shown.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/06/Screenshot-2020-06-02-at-22.47.38.png" alt="Image" width="600" height="400" loading="lazy"></p>
<h3 id="heading-find-network-request-by-regex-expression">Find network request by regex expression</h3>
<p>Type <code>/.*\min.[c]s+$/</code>. DevTools filters out any resources with filenames that end with a <code>min.c</code> followed by 1 or more <code>s</code> characters.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/06/Screenshot-2020-06-02-at-23.21.34.png" alt="Image" width="600" height="400" loading="lazy"></p>
<h3 id="heading-filter-exclude-out-network-request">Filter (exclude) out network request</h3>
<p>Type <code>-min.js</code>. DevTools filters out all files that contain <code>min.js</code>. If any other file matches the pattern they will also be filtered out and won't be visible in the network panel.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/06/Screenshot-2020-06-02-at-22.51.50.png" alt="Image" width="600" height="400" loading="lazy"></p>
<h3 id="heading-use-property-filter-to-see-network-request-by-a-certain-domain">Use property filter to see network request by a certain domain</h3>
<p>Type <code>domain:code.jquery.com</code> into the filter area. It will only show network requests that belong to the URL <code>code.jquery.com</code>.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/06/Screenshot-2020-06-02-at-22.54.22.png" alt="Image" width="600" height="400" loading="lazy"></p>
<h3 id="heading-find-network-request-by-resource-type">Find network request by resource type</h3>
<p>If you only want to see which font(s) file is being used on a certain page click <code>Font</code>:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/06/Screenshot-2020-06-02-at-23.03.41.png" alt="Image" width="600" height="400" loading="lazy">
<em>Filtering network requests by "font" type files only</em></p>
<p>Or if you only want to see the web socket files being loaded on a certain page click <code>WS</code>:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/06/Screenshot-2020-06-02-at-23.05.55.png" alt="Image" width="600" height="400" loading="lazy">
<em>Filtering network requests by "web socket" type files only</em></p>
<p>You can also go one step further and view both <code>Font</code> &amp; <code>WS</code> files together. Simply click on <code>Font</code> first and then <code>cmd</code> click on <code>WS</code> to multi-select tabs. (If you are on a Windows machine you can multi-select by using <code>ctrl</code> click).</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/06/Screenshot-2020-06-02-at-23.08.48.png" alt="Image" width="600" height="400" loading="lazy">
<em>Multi selecting multiple resource types by "cmd` click on types</em></p>
<hr>
<p>That is it for this tutorial. If you found it useful do share it with your colleagues and let me know what you think as well on <a target="_blank" href="https://twitter.com/adeelibr"><strong>twitter.com/adeelibr</strong></a><strong>.</strong></p>
 ]]>
                </content:encoded>
            </item>
        
    </channel>
</rss>
