What causes an exception when a space bar is recorded during a keypress event?

I encountered a problem in my code, here it is:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <script>
        function typeWriter() {

            function genOutput() {

                function genText() {
                    //generate random alphabet via ASCII char code
                    return String.fromCharCode(0|Math.random()*26+97);
                }

                const text = document.getElementById("genText");
                text.textContent = genText() + text.textContent;
            }

            const text = document.getElementById("genText");
            const score = document.getElementById("scoreBoard");

            text.textContent = "";
            window.setInterval(genOutput, 400);  //automatically generate one charracter per 0.4 sec
            document.addEventListener('keypress', (e) => {
                const input = String.fromCharCode(e.charCode);
                const lastCharacter = text.textContent.charAt(text.textContent.length-1);
                if (input == lastCharacter) {
                    const newText = text.textContent.slice(0, -1);
                    text.textContent = newText;
                    score.innerText = "" + (parseInt(score.innerText)+3);
                    
                }
                else if (input == " ") {
                    //check if user type space bar
                    alert("Click to continue");   //if remove this alert will occur exception
                }
                else {
                    score.innerText = "" + (parseInt(score.innerText)-1);
                }
            })
        }
    </script>
    <div class="container">
        <p id="title">Typewriter 2.0</p>
    </div>
    <div class="container">
        <h1 id="genText">Typed correct +3 pt, incorrect -1 pt</h1><br>
        <button id="startBtn" onclick="typeWriter()">Click to Start</button>
        <span>Score: </span><span id="scoreBoard">10</span>
    </div>
</body>
</html>

The provided code showcases a typewriter web game that randomly generates an alphabet every 400ms and removes the last character if typed correctly. However, there is an issue when the user types the space bar as it restarts the countdown interval and generates multiple alphabets at once. To prevent this exception, an alert function was added upon typing the space bar which acts as a pause button. Can anyone provide insights on why this exception occurs? Your help is highly appreciated!

Answer №1

Once you press the click to start button, it gains focus making the spacebar activate the button again.

An alert shifted the focus away from the button, causing the spacebar to no longer trigger the event.

To eliminate focus, you can include a blur event (on the button) to disable the spacebar's function of clicking the button.

e.target.blur();

In the event listener, e.target refers to the clicked button, enabling us to automatically execute the blur event.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8>
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <script>
        function typeWriter() {

            function genOutput() {

                function genText() {
                    //generate random alphabet using ASCII char code
                    return String.fromCharCode(0|Math.random()*26+97);
                }

                const text = document.getElementById("genText");
                text.textContent = genText() + text.textContent;
            }

            const text = document.getElementById("genText");
            const score = document.getElementById("scoreBoard");

            text.textContent = "";
            window.setInterval(genOutput, 400);  //generates one character every 0.4 seconds
            document.addEventListener('keypress', (e) => {
            e.target.blur(); // removes focus from the button to prevent spacebar continuation 
                const input = String.fromCharCode(e.charCode);
                const lastCharacter = text.textContent.charAt(text.textContent.length-1);
                if (input == lastCharacter) {
                    const newText = text.textContent.slice(0, -1);
                    text.textContent = newText;
                    score.innerText = "" + (parseInt(score.innerText)+3);
                    
                }
                else if (input == " ") {
                    //check if user typed space bar
                 //   alert("Click to continue");   //exception will occur if this alert is removed
                }
                else {
                    score.innerText = "" + (parseInt(score.innerText)-1);
                }
            })
        }
    </script>
    <div class="container">
        <p id="title">Typewriter 2.0</p>
    </div>
    <div class="container">
        <h1 id="genText">Typed correctly: +3 points, incorrect: -1 point.</h1><br>
        <button id="startBtn" onclick="typeWriter()">Click to Start</button>
        <span>Score: </span><span id="scoreBoard">10</span>
    </div>
</body>
</html>

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Using a custom font with Next.js and Tailwind: Font applied successfully but not displaying correctly

In my project with Next.js (9.4.4) and Tailwind.css (1.4.6), I am incorporating a custom font named SpaceGrotesk. To ensure its functionality, I stored the font files in public/fonts/spaceGrotesk, and then adjusted my configurations as below: // next.confi ...

What are the ways to utilize vue-i18n setup within and beyond Vue components when working with Quasar?

Hello, fellow developers. I am currently working on implementing internationalization in Quasar, using Vue 3 (Composition API) and vue-i18n. My goal is to make internationalization available throughout the entire application, not just within Vue components ...

Problem with the operation of SetInterval/ClearInterval loop

While I am aware that this question has been addressed previously, none of the solutions provided seemed to resolve my specific issue. The problem lies within my timer function which, upon invocation, is supposed to utilize setInterval to run every second ...

Trouble arises when trying to create an auto suggest text box using PHP and Javascript

I've been working on creating a basic auto-suggest input feature that connects to a MySql database to retrieve data. However, I'm facing a particular issue where when I enter the name of an object that I know exists in the database, the input bar ...

Discovering a particular element involves iterating through the results returned by the findElements method in JavaScript

I am attempting to locate and interact with a specific item by comparing text from a list of items. The element distinguished by .list_of_items is a ul that consists of a list of li>a elements. I am uncertain about how to transfer the determined elemen ...

How do I display the frequency of a number occurring multiple times within an array in JavaScript?

I'm currently working on this task: Create a JavaScript function that prompts the user for a number and then displays how many times that number appears in an array. To achieve this, I am using parseFloat to convert the user input from a string to ...

Retrieve the user's IP address from the request rather than Cloudflare's IP address

Cloudflare alters the IP addresses of incoming requests as it acts as a middleman between my website and the Internet, functioning as a proxy. Is there a way to retrieve the original IP address of the request, rather than Cloudflare's IP address? I h ...

Issues with importing Bootstrap in JavaScript

Utilizing Bootstrap in both HTML and JavaScript/TypeScript has been my recent endeavor. I have successfully imported the minified versions of Bootstrap JS and CSS in my HTML file and incorporated this line of code in my TypeScript: import * as bootstrap fr ...

Issue in JavaScript on IE9: SCRIPT5022 error: DOM Exception - INVALID_CHARACTER_ERR (5)

I am encountering an error with the following line of code: var input2 = document.createElement('<input name=\'password\' type=\'password\' id=\'password\' onblur=\'checkCopy(th ...

Retrieving parameters from within iframe (child)

I currently have an embedded Iframe within a website, with both residing on different domains that I own. My goal is to pass a query parameter to the src attribute of the iframe. <iframe id="iframe" title="Survey" allowtr ...

Utilizing the reduce method to process an object and return a collection of objects

I have a complex object that I'm trying to transform using the reduce method, but I'm struggling to figure it out... Here is the structure of my object: const object = { ... } My goal is to create a new object with keys that are a combinatio ...

Tooltip positioned within a custom container using Material UI

Currently, as part of my Chrome extension development utilizing React and Material UI, I am implementing an inject page strategy. I have managed to set up a tooltip for the Fab button, but unfortunately, it appears outside the DOM of my extension. Upon ins ...

Is there a way to ensure one request completes before allowing another to be executed in Express/Node?

I am currently working on a task that involves fetching data from a third-party API (iTunes) to search for content provided by the API. The backend, which is handled by Express and Node, will interact with this third-party API. My goal is to trigger a POST ...

Looping through properties of objects with the help of angularJS ng-repeat is known as using objects['propertyname&#

What is the best way to iterate over an object with property names like this? $scope.myobjects = [ { 'property1': { id: 0, name: 'someone' } }, { 'property2': { id: 1, name: ' ...

Retrieve a particular element from a JavaScript object by iterating through it with the .each()

Welcome, fellow developers! I am currently facing a challenge in my ticketing system project involving getting the 'title' variable from a node.js loop. The objective is to use this variable as a placeholder so that when a user wants to edit a t ...

Concealing a hyperlink depending on the value chosen in a dropdown menu

Looking for guidance on how to use jQuery to read the current value of a drop-down list and hide a specific link based on that value. The drop-down list is for selecting the language/locale. For example, when "English" is selected, I want the link to be h ...

What is the best way to make this relative path function in JavaScript?

My file structure is organized in the following way: multiple folders a subfolder _includes getStatisticsTable.php _templates StatisticsWrapper.html Within StatisticsWrapper.html, I am using jQuery's .get() method to fetch external data which ...

Error: The module 'cropbox' could not be located. 2

I posed the inquiry Module not found: Error: Can't resolve 'cropbox' Unfortunately, I did not receive a response, prompting me to delve into more specific issues and scour StackOverflow for solutions. After investigating, I identified thr ...

Creating a TypeScript rule/config to trigger an error when a React Functional Component does not return JSX

I've encountered a recurring issue where I forget to include a return statement when rendering JSX in a functional component. Here's an example of the mistake: const Greetings = function Greetings({name}) { <div>Greetings {name}</div& ...

Tips for customizing the appearance of buttons in a JavaScript bxSlider

Take a look at my landing page: In the upper section, you'll find three buttons that allow you to switch between different slides. These buttons are named: credi5, credi10, and credi15. Now, I want to replace those buttons with images... specificall ...