Изменение цвета фона div в событии щелчка дает неожиданные (или это ожидаемо?) Результат

#javascript #html #css #events

Вопрос:

Я работаю над игрой в угадывание слов, и когда пользователь нажимает букву на созданной мной визуальной клавиатуре, я хочу, чтобы цвет фона этой буквы изменился (светло-зеленый, если угадано правильно, серый, если неверно). Однако фон по умолчанию (заданный классом «буква»), похоже, не заменяется должным образом после нажатия. Вместо этого неокрашенное поле (без радиуса границы и т. Д.) С новым цветом фона накладывается на цвет фона по умолчанию (это визуально очевидно). Мне интересно знать, почему это происходит. Не мог бы кто-нибудь, пожалуйста, просветить меня? Известно ли это явление? Или это связано с моим событием и использованием e.target?

Пожалуйста, ознакомьтесь с моими HTML, CSS и Javascript ниже.

 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) amp;amp; !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> 

Ответ №1:

Это связано с тем, что вы устанавливаете background-color e.target значение, которое может не совпадать с элементом letter класса. Целью события является элемент, который был фактически нажат и может быть дочерним (например p , тег). Это происходит потому, что события всплывают в dom и запускают любых слушателей, с которыми они сталкиваются. Чтобы получить элемент, к которому прикреплен прослушиватель событий, используйте e.currentTarget

 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.currentTarget.firstChild.textContent.toLocaleUpperCase();

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

            // Change background of correctly guessed letter
            $(e.currentTarget).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) amp;amp; !check.length) {

            // Change background of 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>