Event Handling in JavaScript

Introduction:

In this lesson, we embark on a journey to understand event handling in JavaScript, a fundamental concept for creating responsive and interactive decentralized applications (dApps).

Mastering event handling is essential for beginners stepping into the world of web3 frontend development.

Remember, watching the lesson video will offer a deeper understanding of this topic.

Learning Objectives:

By the end of this lesson, you will be able to:

  1. Comprehend the concept of events in JavaScript.
  2. Utilize the addEventListener() method to handle events.
  3. Implement event handling in practical web3 application scenarios.

Lesson Video:


What is an Event in JavaScript?

An event in JavaScript refers to an action or occurrence recognized by the software, typically user actions like clicks, key presses, or system-generated events. These events can be used to trigger JavaScript functions. For example, when a user clicks a button, it might trigger a function that changes the color of a webpage element.

Event Handling Techniques:

  1. HTML Event Handler Attributes:
    • These handlers are written directly within HTML tags (e.g., <button onclick="functionName()">Click me</button>).
    • While convenient, they are generally considered outdated and can lead to less maintainable code.
  2. DOM Level 0 Event Handlers:
    • Assigning a function directly to an event property of an element (e.g., element.onclick = function() {...}).
    • Simple but only allows one event handler per event type.
  3. DOM Level 2 Event Handlers (Recommended):
    • Using addEventListener() to attach event handlers (e.g., element.addEventListener('click', functionHandler)).
    • It allows multiple event handlers for the same event and more flexibility.

Example Codes for Practical Application:

Expanding the Capstone Project

Expanding on our Token Minter dApp, let’s enhance its features using what you learned from this lesson.

Existing Capstone Project Code from Previous Lesson:

Javascript Code:

// External JavaScript file for the global script

// Declare variables to track the total minted tokens and set a minting limit
let totalMintedTokens = 0;
const mintingLimit = 10000; // Set a limit for total tokens that can be minted

document.addEventListener('DOMContentLoaded', function() {
    const mintButton = document.querySelector('#mint button');
    const walletInput = document.querySelector('#walletAddress');
    const tokenInput = document.querySelector('#tokenAmount');

    mintButton.addEventListener('click', function() {
        let walletAddress = walletInput.value;
        let tokenAmount = parseInt(tokenInput.value);

        // Validation for wallet address and token amount
        if(walletAddress !== '' && !isNaN(tokenAmount) && tokenAmount > 0) {
            // Call function to update minted tokens and get result
            let mintResult = updateMintedTokens(tokenAmount);

            if(mintResult) {
                // Notify the user about the minting process
                alert(`Minting ${tokenAmount} tokens to wallet: ${walletAddress}`);
            }
        } else {
            // Alert for invalid input
            alert('Please enter a valid wallet address and a positive number of tokens to mint.');
        }
    });
});

// Function to update the total minted tokens
function updateMintedTokens(amount) {
    let successfullyMinted = false;

    // Use a for loop to add tokens to the total, respecting the minting limit
    for(let i = 0; i < amount; i++) {
        if (totalMintedTokens < mintingLimit) {
            totalMintedTokens++;
            successfullyMinted = true;
        } else {
            alert('Minting limit reached. No more tokens can be minted.');
            break; // Exit the loop if the minting limit is reached
        }
    }

    document.getElementById('totalMinted').textContent = `Total Minted: ${totalMintedTokens}`;
    return successfullyMinted;
}

CSS Code:

/* External CSS */
 
/* IMPORTS */
@import url('https://fonts.googleapis.com/css2?family=Roboto:wght@400;700&display=swap');
 
/* CSS Variables for consistent theming and easy maintenance */
:root {
    --font-family: 'Roboto', sans-serif;
    --bg-color: #f4f4f4;
    --bg-gradient: linear-gradient(to right, #630404, #e040fb, #6a027c);
    --nav-hover-bg-color: #630404;
    --nav-hover-text-color: #f3e40d;
    --text-color-white: #ffffff;
    --header-bg-color: #333;
    --header-text-color: white;
    --subtitle-text-color: #aaa;
    --paragraph-color: #cfbdbd;
    --main-border-color: #333;
    --article-border-color: grey;
    --form-border-color: #ddd;
    --input-border-color: #ccc;
    --button-hover-color: #f5f121;
    --invalid-input-border-color: red;
    --placeholder-color: #888;
    --info-text-color: #521f1f;
}
 
/* BODY */
body {
    font-family: var(--font-family);
    background-color: var(--bg-color);
    background: var(--bg-gradient);
}
 
/* NAVIGATION */
nav > ul > li {
    display: inline;
    margin-right: 20px;
    text-align: center;
    padding: 10px;
    flex: 1;
}
 
nav a:hover, nav a:focus {
    background-color: var(--nav-hover-bg-color);
    color: var(--nav-hover-text-color);
}
 
/* HYPERLINKS */
a[href^="#"] {
    text-decoration: none;
    color: var(--text-color-white);
}
 
/* HEADINGS */
header {
    background: var(--header-bg-color);
    color: var(--header-text-color);
    padding: 10px;
    text-align: center;
    display: flex;
    justify-content: space-between;
    align-items: center;
}
 
h1 {
    font-weight: 700;
    position: relative;
}
 
h1::after {
    content: '...the future of token minting';
    display: block;
    text-align: center;
    color: var(--subtitle-text-color);
    position: absolute;
    width: 100%;
    left: 0;
    top: 100%;
    font-size: 0.55em;
}
 
h1, h2, h3 {
    font-weight: 700;
}
 
h2 + p {
    color: var(--paragraph-color);
}
 
/* MAIN */
main {
    display: flex;
    flex-direction: row;
    gap: 10px;
}
 
/* ARTICLE */
article {
    margin-bottom: 15px;
    padding: 10px;
    border: 1px solid var(--article-border-color);
    flex: 1;
}
 
article p {
    margin-bottom: 20px;
    border: 1px solid var(--article-border-color);
    padding: 15px;
}
 
/* IDs */
#mint {
    background-color: #eaeaea;
    padding: 15px;
    margin-top: 10px;
}
 
#mint form {
    padding: 10px;
    border: 1px solid var(--form-border-color);
    margin-top: 10px;
    display: flex;
    flex-direction: column;
    gap: 10px;
}
 
#mint input,
#mint button {
    padding: 10px;
    margin-bottom: 10px;
    border: 1px solid var(--input-border-color);
    flex: 1;
}

#totalMinted {
    color: var(--info-text-color);
}
 
/* PARAGRAPH */
p {
    line-height: 3.5;
}
 
/* MEDIA QUERY */
@media (min-width: 768px) and (max-width: 1024px) {
    body {
        background: var(--bg-gradient);
    }
    main {
        flex-direction: row;
    }
}
 
@media (max-width: 767px) {
    nav ul {
        flex-direction: column;
    }
    .button {
        padding: 15px;
    }
}
 
/* ANIMATION AND TRANSITION */
@keyframes pulse {
    0% { transform: scale(1); }
    50% { transform: scale(1.1); }
    100% { transform: scale(1); }
}
 
.button {
    animation: pulse 2s infinite;
}
 
a {
    transition: color 0.5s ease;
}
 
a:hover {
    color: var(--button-hover-color);
}
 
@media (max-width: 600px) {
    .container {
        flex-direction: column;
    }
}
 
input:invalid {
    border-color: var(--invalid-input-border-color);
}
 
::placeholder {
    color: var(--placeholder-color);
    opacity: 1;
}

HTML Code:

<!DOCTYPE html> <!-- Defines document type and HTML version -->
<html lang="en"> <!-- Sets the language of the page -->
 
<head>
    <meta charset="UTF-8"> <!-- Sets character encoding for the document -->
    <meta name="viewport" content="width=device-width, initial-scale=1.0"> <!-- Ensures proper rendering on mobile devices -->
    <title>Token Minter dApp</title> <!-- Title of the webpage -->
    <link rel="stylesheet" href="/globalstyles.css"> <!-- Link to external CSS file -->
    <script src="/globalscript.js"></script> <!-- Link to external CSS file -->
</head>
 
<body>
    <header>
        <!-- Site header with navigation -->
        <h1>Token Minter dApp</h1>
        <nav>
            <!-- Navigation links -->
            <ul>
                <li><a href="#home">Home</a></li>
                <li><a href="#mint">Mint Tokens</a></li>
                <li><a href="#about">About</a></li>
            </ul>
        </nav>
    </header>
     
    <main>
        <!-- Main content section -->
        <article id="home">
            <!-- Introduction article -->
            <h2>Introduction to Token Minting</h2>
            <p>This dApp allows users to mint their own tokens on the blockchain.</p>
        </article>
         
        <section id="mint">
            <!-- Token minting form section -->
            <h2>Mint Your Tokens</h2>
            <form action="#">
                <!-- Form for token minting -->
                <input type="text" placeholder="Enter your wallet address" id="walletAddress">
                <input type="number" placeholder="Token amount" id="tokenAmount">
                <button class="button" type="button">Mint</button>
            </form>
            <p id="totalMinted">Total Minted: 0</p>
        </section>
         
        <aside>
            <!-- Sidebar with additional information -->
            <h3>Learn More:</h3>
            <p>Explore more about blockchain technology.</p>
        </aside>
    </main>
     
    <footer>
        <!-- Footer with contact information -->
        <p>Contact us at <a href="mailto:hello@dProgrammingUniversity.com">hello@dProgrammingUniversity.com</a></p>
    </footer>
</body>
</html>

Enhance the Capstone Project with New Features from this Lesson:

Javascript Code:

// External JavaScript file for the global script

// Declare variables to track the total minted tokens and set a minting limit
let totalMintedTokens = 0;
const mintingLimit = 10000; // Set a limit for total tokens that can be minted

document.addEventListener('DOMContentLoaded', function() {
    const mintButton = document.querySelector('#mint button');
    const walletInput = document.querySelector('#walletAddress');
    const tokenInput = document.querySelector('#tokenAmount');
    const mintStatus = document.querySelector('#mintStatus'); // Access the mint status element

    mintButton.addEventListener('click', function() {
        let walletAddress = walletInput.value;
        let tokenAmount = parseInt(tokenInput.value);

        // Validation for wallet address and token amount
        if(walletAddress !== '' && !isNaN(tokenAmount) && tokenAmount > 0) {
            // Call function to update minted tokens and get result
            let mintResult = updateMintedTokens(tokenAmount);

            if(mintResult) {
                // Update the mint status in the DOM
                mintStatus.textContent = `Successfully minted ${tokenAmount} tokens to wallet: ${walletAddress}`;
            }
        } else {
            // Update the mint status for invalid input
            mintStatus.textContent = 'Invalid wallet address or token amount. Please try again.';
        }
    });
});

// Function to update the total minted tokens
function updateMintedTokens(amount) {
    let successfullyMinted = false;

    // Use a for loop to add tokens to the total, respecting the minting limit
    for(let i = 0; i < amount; i++) {
        if (totalMintedTokens < mintingLimit) {
            totalMintedTokens++;
            successfullyMinted = true;
        } else {
            // Update the mint status if the limit is reached
            document.querySelector('#mintStatus').textContent = 'Minting limit reached. No more tokens can be minted.';
            break; // Exit the loop if the minting limit is reached
        }
    }

    document.getElementById('totalMinted').textContent = `Total Minted: ${totalMintedTokens}`;
    return successfullyMinted;
}

AFTER:

Your code may look something like the following after applying the above adjustment from this lesson:

Javascript Code:

// External JavaScript file for the global script

// Declare variables to track the total minted tokens and set a minting limit
let totalMintedTokens = 0;
const mintingLimit = 10000; // Set a limit for total tokens that can be minted

document.addEventListener('DOMContentLoaded', function() {
    const mintButton = document.querySelector('#mint button');
    const walletInput = document.querySelector('#walletAddress');
    const tokenInput = document.querySelector('#tokenAmount');
    const mintStatus = document.querySelector('#mintStatus'); // Access the mint status element

    mintButton.addEventListener('click', function() {
        let walletAddress = walletInput.value;
        let tokenAmount = parseInt(tokenInput.value);

        // Validation for wallet address and token amount
        if(walletAddress !== '' && !isNaN(tokenAmount) && tokenAmount > 0) {
            // Call function to update minted tokens and get result
            let mintResult = updateMintedTokens(tokenAmount);

            if(mintResult) {
                // Update the mint status in the DOM
                mintStatus.textContent = `Successfully minted ${tokenAmount} tokens to wallet: ${walletAddress}`;
            }
        } else {
            // Update the mint status for invalid input
            mintStatus.textContent = 'Invalid wallet address or token amount. Please try again.';
        }
    });
});

// Function to update the total minted tokens
function updateMintedTokens(amount) {
    let successfullyMinted = false;

    // Use a for loop to add tokens to the total, respecting the minting limit
    for(let i = 0; i < amount; i++) {
        if (totalMintedTokens < mintingLimit) {
            totalMintedTokens++;
            successfullyMinted = true;
        } else {
            // Update the mint status if the limit is reached
            document.querySelector('#mintStatus').textContent = 'Minting limit reached. No more tokens can be minted.';
            break; // Exit the loop if the minting limit is reached
        }
    }

    document.getElementById('totalMinted').textContent = `Total Minted: ${totalMintedTokens}`;
    return successfullyMinted;
}

CSS Code:

/* External CSS */
 
/* IMPORTS */
@import url('https://fonts.googleapis.com/css2?family=Roboto:wght@400;700&display=swap');
 
/* CSS Variables for consistent theming and easy maintenance */
:root {
    --font-family: 'Roboto', sans-serif;
    --bg-color: #f4f4f4;
    --bg-gradient: linear-gradient(to right, #630404, #e040fb, #6a027c);
    --nav-hover-bg-color: #630404;
    --nav-hover-text-color: #f3e40d;
    --text-color-white: #ffffff;
    --header-bg-color: #333;
    --header-text-color: white;
    --subtitle-text-color: #aaa;
    --paragraph-color: #cfbdbd;
    --main-border-color: #333;
    --article-border-color: grey;
    --form-border-color: #ddd;
    --input-border-color: #ccc;
    --button-hover-color: #f5f121;
    --invalid-input-border-color: red;
    --placeholder-color: #888;
    --info-text-color: #521f1f;
}
 
/* BODY */
body {
    font-family: var(--font-family);
    background-color: var(--bg-color);
    background: var(--bg-gradient);
}
 
/* NAVIGATION */
nav > ul > li {
    display: inline;
    margin-right: 20px;
    text-align: center;
    padding: 10px;
    flex: 1;
}
 
nav a:hover, nav a:focus {
    background-color: var(--nav-hover-bg-color);
    color: var(--nav-hover-text-color);
}
 
/* HYPERLINKS */
a[href^="#"] {
    text-decoration: none;
    color: var(--text-color-white);
}
 
/* HEADINGS */
header {
    background: var(--header-bg-color);
    color: var(--header-text-color);
    padding: 10px;
    text-align: center;
    display: flex;
    justify-content: space-between;
    align-items: center;
}
 
h1 {
    font-weight: 700;
    position: relative;
}
 
h1::after {
    content: '...the future of token minting';
    display: block;
    text-align: center;
    color: var(--subtitle-text-color);
    position: absolute;
    width: 100%;
    left: 0;
    top: 100%;
    font-size: 0.55em;
}
 
h1, h2, h3 {
    font-weight: 700;
}
 
h2 + p {
    color: var(--paragraph-color);
}
 
/* MAIN */
main {
    display: flex;
    flex-direction: row;
    gap: 10px;
}
 
/* ARTICLE */
article {
    margin-bottom: 15px;
    padding: 10px;
    border: 1px solid var(--article-border-color);
    flex: 1;
}
 
article p {
    margin-bottom: 20px;
    border: 1px solid var(--article-border-color);
    padding: 15px;
}
 
/* IDs */
#mint {
    background-color: #eaeaea;
    padding: 15px;
    margin-top: 10px;
}
 
#mint form {
    padding: 10px;
    border: 1px solid var(--form-border-color);
    margin-top: 10px;
    display: flex;
    flex-direction: column;
    gap: 10px;
}
 
#mint input,
#mint button {
    padding: 10px;
    margin-bottom: 10px;
    border: 1px solid var(--input-border-color);
    flex: 1;
}

#totalMinted {
    color: var(--info-text-color);
}
 
/* PARAGRAPH */
p {
    line-height: 3.5;
}
 
/* MEDIA QUERY */
@media (min-width: 768px) and (max-width: 1024px) {
    body {
        background: var(--bg-gradient);
    }
    main {
        flex-direction: row;
    }
}
 
@media (max-width: 767px) {
    nav ul {
        flex-direction: column;
    }
    .button {
        padding: 15px;
    }
}
 
/* ANIMATION AND TRANSITION */
@keyframes pulse {
    0% { transform: scale(1); }
    50% { transform: scale(1.1); }
    100% { transform: scale(1); }
}
 
.button {
    animation: pulse 2s infinite;
}
 
a {
    transition: color 0.5s ease;
}
 
a:hover {
    color: var(--button-hover-color);
}
 
@media (max-width: 600px) {
    .container {
        flex-direction: column;
    }
}
 
input:invalid {
    border-color: var(--invalid-input-border-color);
}
 
::placeholder {
    color: var(--placeholder-color);
    opacity: 1;
}

HTML Code:

<!DOCTYPE html> <!-- Defines document type and HTML version -->
<html lang="en"> <!-- Sets the language of the page -->
 
<head>
    <meta charset="UTF-8"> <!-- Sets character encoding for the document -->
    <meta name="viewport" content="width=device-width, initial-scale=1.0"> <!-- Ensures proper rendering on mobile devices -->
    <title>Token Minter dApp</title> <!-- Title of the webpage -->
    <link rel="stylesheet" href="/globalstyles.css"> <!-- Link to external CSS file -->
    <script src="/globalscript.js"></script> <!-- Link to external CSS file -->
</head>
 
<body>
    <header>
        <!-- Site header with navigation -->
        <h1>Token Minter dApp</h1>
        <nav>
            <!-- Navigation links -->
            <ul>
                <li><a href="#home">Home</a></li>
                <li><a href="#mint">Mint Tokens</a></li>
                <li><a href="#about">About</a></li>
            </ul>
        </nav>
    </header>
     
    <main>
        <!-- Main content section -->
        <article id="home">
            <!-- Introduction article -->
            <h2>Introduction to Token Minting</h2>
            <p>This dApp allows users to mint their own tokens on the blockchain.</p>
        </article>
         
        <section id="mint">
            <h2>Mint Your Tokens</h2>
            <p id="totalMinted">Total Minted: 0</p>
            
            <!-- Token minting form section -->
            <form action="#">
                <!-- Form for token minting -->
                <input type="text" placeholder="Enter your wallet address" id="walletAddress">
                <input type="number" placeholder="Token amount" id="tokenAmount">
                <button class="button" type="button">Mint</button>
            </form>
            
            <!-- Display minting status -->
            <p id="mintStatus">Ready to mint tokens.</p>
        </section>
         
        <aside>
            <!-- Sidebar with additional information -->
            <h3>Learn More:</h3>
            <p>Explore more about blockchain technology.</p>
        </aside>
    </main>
     
    <footer>
        <!-- Footer with contact information -->
        <p>Contact us at <a href="mailto:hello@dProgrammingUniversity.com">hello@dProgrammingUniversity.com</a></p>
    </footer>
</body>
</html>

Conclusion:

Understanding and implementing event handling is a crucial step towards developing interactive and responsive web3 applications.

This skill lays the groundwork for creating user-engaged dApps that respond to various actions, enhancing the user experience.

Resources & References:

To deepen your understanding of this lesson, you can explore the following resources:

  1. MDN Web Docs – Introduction to events
  2. MDN Web Docs – JavaScript Basics reference
  3. W3Schools – JavaScript Tutorial
  4. Freecodecamp – JavaScript Handbook

These resources provide comprehensive guides and examples that will be invaluable as you learn and apply them in your journey of Web3 frontend development.


Support:

If you need help with this lesson, questions, suggestions and improvement. The best way to get help is to use the comment below:
1. First check existing comments if your questions have been answered before posting.
2. If no existing related question with an answer, then you can post a new one (kindly avoid duplicating previously asked and answered questions).

NOTE: This is the most recommended way of getting support directly from the instructor of this course. Posting on other platforms like Discord may get support from other community members and not from the course instructor directly.

Images|Videos|Links: To support your question with a screenshot, Github repo link or other media, kindly upload it somewhere online like Drive/Dropbox or Github (for codes) first, then post the link to it in your comment. Please do not upload media/codes directly, it may fail or cause your comment to be deleted.

Please ONLY post questions that are specific to this lesson not the entire course to ensure others can find it helpful. Each lesson allows comments relating to it ONLY. Off-lesson questions will be deleted even if they relate to this course as a whole but as long as they are not specific to this lesson, they are not allowed.

Post a comment

Leave a Comment

By using this website you agree to accept our Privacy Policy and Terms & Conditions