The surprising outcome of altering the background color of a div during a click event

Currently, I am engrossed in crafting a word guessing game. In this game, I've constructed a visual keyboard. When a user selects a letter on this keyboard, I desire the background color of that specific letter to adjust accordingly - light green if the guess is accurate, and grey if it's incorrect. However, I am encountering an issue where the default background (specified with the 'letter' class) fails to get properly replaced post-click. Instead, what occurs is a new background color overlays the default one, presenting as a raw, unstyled box sans border radius or any other stylings. Visually, this discrepancy is rather evident. I'm curious as to why this is happening. Would someone be kind enough to shed some light on this matter for me? Is this an established phenomenon within web development circles? Or could it have something to do with the event handling and my utilization of the e.target property?

Below, you will find snippets of my HTML, CSS, and Javascript implementation.

const currentWord = "abc"

$('.keyboard .row .letter').click(function(e) {
        
    // Check if 'currentWord' contains clicked letter 
    let check = [];
    currentWord.split('').forEach(function(letter, i) {

        let clickedLetter = e.target.firstChild.textContent.toLocaleUpperCase();

        if(clickedLetter === letter.toLocaleUpperCase()) {

            // Change background of correctly guessed letter
            $(e.target).css('background-color','lightgreen');

            // Make letter appear in letter box
            $(`#${letter} .word-letter`).text(clickedLetter).fadeOut(1).fadeIn(250);
            check.push(1);

        } else if((i === currentWord.length - 1) && !check.length) {

            // Change background of incorrectly guessed letter
            $(e.target).css('background-color', 'grey');
        }   
  })
})
/* KEYBOARD */
        .keyboard {
            grid-column: 2/5;
            grid-row: 6/8;
            display: flex;
            flex-direction: column;
            align-items: center;
            justify-content: center;
            background-color: rgb(223, 255, 196);
        }
        
        .row {
            height: 40%;
            width: 100%;
            font-size: 2em;
            display: flex;
            justify-content: center;
        }
        
        .letter {
            text-align: center;
            width: 5%;
            background-color: rgb(158, 228, 255);
            margin: 1%;
            border-radius: 10px;
            box-shadow: 3px 3px lightgray;
        }
        
        .letter:hover {
            background-color: rgb(255, 138, 255);
            cursor: pointer;
        }
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<div class="keyboard">
    <div class="row">
        <div class="letter"><p>Q</p></div>
        <div class="letter"><p>W</p></div>
        <div class="letter"><p>E</p></div>
        <div class="letter"><p>R</p></div>
        <div class="letter"><p>T</p></div>
        <div class="letter"><p>Y</p></div>
        <div class="letter"><p>U</p></div>
        <div class="letter"><p>I</p></div>
        <div class="letter"><p>O</p></div>
        <div class="letter"><p>P</p></div>
    </div>
    <div class="row">
        <div class="letter"><p>A</p></div>
        <div class="letter"><p>S</p></div>
        <div class="letter"><p>D</p></div>
        <div class="letter"><p>F</p></div>
        <div class="letter"><p>G</p></div>
        <div class="letter"><p>H</p></div>
        <div class="letter"><p>J</p></div>
        <div class="letter"><p>K</p></div>
        <div class="letter"><p>L</p></div>
    </div>
    <div class="row">
        <div class="letter"><p>Z</p></div>
        <div class="letter"><p>X</p></div>
        <div class="letter"><p>C</p></div>
        <div class="letter"><p>V</p></div>
        <div class="letter"><p>B</p></div>
        <div class="letter"><p>N</p></div>
        <div class="letter"><p>M</p></div>
    </div>
</div>

Answer №1

That's because when you set the background-color on e.target, it may not target the element with the letter class. The event target refers to the element that was actually clicked and could be a child element (e.g. the p tag). This behavior occurs because events bubble up the DOM and trigger any listeners they encounter. To access the element where the event listener is attached, use e.currentTarget

const currentWord = "abc"

$('.keyboard .row .letter').click(function(e) {
        
    // Check if 'currentWord' contains the clicked letter 
    let check = [];
    currentWord.split('').forEach(function(letter, i) {

        let clickedLetter = e.currentTarget.firstChild.textContent.toLocaleUpperCase();

        if(clickedLetter === letter.toLocaleUpperCase()) {

            // Change the background of the correctly guessed letter
            $(e.currentTarget).css('background-color','lightgreen');

            // Display the letter in the letter box
            $(`#${letter} .word-letter`).text(clickedLetter).fadeOut(1).fadeIn(250);
            check.push(1);

        } else if((i === currentWord.length - 1) && !check.length) {

            // Change the background of the incorrectly guessed letter
            $(e.currentTarget).css('background-color', 'grey');
        }   
  })
})
/* KEYBOARD */
.keyboard {
    grid-column: 2/5;
    grid-row: 6/8;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    background-color: rgb(223, 255, 196);
}

.row {
    height: 40%;
    width: 100%;
    font-size: 2em;
    display: flex;
    justify-content: center;
}

.letter {
    text-align: center;
    width: 5%;
    background-color: rgb(158, 228, 255);
    margin: 1%;
    border-radius: 10px;
    box-shadow: 3px 3px lightgray;
}

        .letter:hover {
            background-color: rgb(255, 138, 255);
            cursor: pointer;
        }
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<div class="keyboard">
    <div class="row">
        <div class="letter"><p>Q</p></div>
        <div class="letter"><p>W</p></div>
        <div class="letter"><p>E</p></div>
        <div class="letter"><p>R</p></div>
        <div class="letter"><p>T</p></div>
        <div class="letter"><p>Y</p></div>
        <div class="letter"><p>U</p></div>
        <div class="letter"><p>I</p></div>
        <div class="letter"><p>O</p></div>
        <div class="letter"><p>P</p></div>
    </div>
    <div class="row">
        <div class="letter"><p>A</p></div>
        <div class="letter"><p>S</p></div>
        <div class="letter"><p>D</p></div>
        <div class="letter"><p>F</p></div>
        <div class="letter"><p>G</p></div>
        <div class="letter"><p>H</p></div>
        <div class="letter"><p>J</p></div>
        <div class="letter"><p>K</p></div>
        <div class="letter"><p>L</p></div>
    </div>
    <div class="row">
        <div class="letter"><p>Z</p></div>
        <div class="letter"><p>X</p></div>
        <div class="letter"><p>C</p></div>
        <div class="letter"><p>V</p></div>
        <div class="letter"><p>B</p></div>
        <div class="letter"><p>N</p></div>
        <div class="letter"><p>M</p></div>
    </div>
</div>

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

Got a value of `false` for an attribute `closable` that is not meant to be a

Here's the code snippet I have: import { Modal } from "antd"; import styled from "styled-components"; export const StANTModal = styled(Modal)` & .ant-modal-content { border-radius: 20px; overflow: hidden; } `; And ...

Tips for creating a dynamic header background using custom CSS for my website design

As I embark on creating my very first WordPress website using the Blossom Pin Pro theme, I'm encountering an issue where the background image of the header disappears when adjusting the window width. Click here to visit the site If you have a code s ...

Obtain the node identifier within the Angular UI Tree component [angular-ui-tree]

Utilizing Angular UI tree to create a relationship between items and categories has been successful in the default setup. However, a new requirement has emerged to incorporate node/section numbering within the tree for managing hierarchy. I attempted to i ...

The MUI Slider Component is causing the entire page to go blank

I have implemented the Range Slider component: import React from 'react'; import Box from '@mui/material/Box'; import Slider from '@mui/material/Slider'; function valuetext(value) { return `${value}°C`; } export default f ...

Scope variable changes are not being acknowledged by the directive

Here is a directive I am working with: <span ng-show="{{ save_state == 'saved' }}"> Saved </span> <span ng-show="{{ save_state == 'saving' }}"> Saving </span> <span ng-show="{{ save_state == 'error ...

Changes made to code within the node_modules directory do not appear in the browser

I encountered a bug in the vuejs-datepicker project on Github, prompting me to fork the repository. However, despite making changes to the forked project, these alterations are not reflected in my main project that relies on this dependency. Here's a ...

How to Perfectly Position Content with Bootstrap 3's Full Width Image Carousel

Here's my query: Is there a way to adjust the position of my content (such as text) inside the slider responsively? The text can be positioned anywhere within the Div Slider, for example, at 25% from the left and 50% from the top within the Image Di ...

Choose solely the initial and concluding hyperlink within the divs

The structure I am working with is as follows: <div class="navigation_sub_item_background" id="sub_nav_2"> <div class="navigation_sub_item" id="2_1"> <a class="navigation__sub__link" href="?p=2_1"> <span> ...

Strategies for halting the return of a JavaScript function until all AJAX requests have been completed

function processData(data) { //perform some data processing return data; } function test() { $.ajax({ 'url': api1, 'data': { 'use': "200" }, 'dataType': ' ...

Tips for displaying HTML5 validation messages when the input is changed

I am working on a form where I prefer not to submit it directly, as I am making an AJAX call instead. However, I still want the HTML5 validation messages to show up when an input field is left empty. I have managed to display the validation message when a ...

Substitute all numerical values with a designated number from a variable

I came across a link that looks like this foo.net/index.php?page=15 My goal is to replace any number after page=xxx and retrieve the new number from a variable Currently, my code only replaces 15 with 16 var num = 16, // What if the str = foo.net/index ...

Alert: Error encountered while attempting to locate the Angular Material core theme within Angular 3, Angular Material, and Angular Material Experimental

After successfully implementing a custom color palette with Material 3 and Angular Material Experimental, I am encountering a warning in the console stating "Could not find Angular Material core theme. Most Material components may not work as expected. For ...

Design a div in the shape of a trapezium with clipped overflow

Is there a way to create a trapezium using CSS/Html/Canvas? I have attempted to do so, but my current method is messy and not practical. div { width:0; margin-left:-1000px; height:100px; border-right:1000px solid lightblue; border-top:60px solid tra ...

Tips for ensuring that an Ajax request successfully executes when a page loads

I have a question about implementing an AJAX request in my code. Currently, I have the text on the screen updating when a dropdown input is selected using 'onchange'. However, I also want this same behavior to occur on page load, but I am struggl ...

Counting Clicks with the Button Counter

I'm having an issue with my jQuery code that is supposed to count button clicks - it stops after just one click. I need help fixing this problem. $(function() { $('.btn').click(function() { $(this).val(this.textContent + 1); }); } ...

The local ESlint plugin is causing issues with installing dependencies on our CI environment

I have developed a personalized ESLint plugin specifically for one project and have not made it public. It is saved in a folder within my project because I only intend to use it internally, and I see no need to create a separate repository for it. However, ...

Ways to prevent horizontal scrolling in an image

Currently, I am working on a scrolling animation page that is optimized for mobile devices. One issue I am encountering is when an element is larger than the screen size, such as when an image is wider than the mobile device. In this scenario, the user can ...

Do these two JavaScript statements behave the same under the principles of functional programming in a React environment?

Is there a rule in functional programming that states these two approaches are equivalent? When working on a React application, I initially passed a function as an attribute using the second version where the first parameter is also passed. Out of curiosi ...

Running a command once the forEach loop is completed in Angular

Within the HTML, I have a function that is triggered by an ng-click: vm.items = []; vm.moveItems = function() { angular.forEach(vm.items, function (item) { $http({ method: 'PUT', url: &apos ...

The container cannot contain the overflowing DIV

I have 4 different divisions named outer, inner, title, and content. My goal is to place the inner div inside the outer div, with both the title and content divs positioned within the inner div, one above the other. I have set the outer and inner divs to b ...