首页 > 解决方案 > 在单击事件中更改 div 的背景颜色会产生意外(或预期?)结果

问题描述

我正在做一个猜词游戏,当用户在我创建的可视键盘上单击一个字母时,我希望该字母的背景颜色发生变化(如果猜对了,则为浅绿色,如果猜错则为灰色)。但是,默认背景(设置为“字母”类)在单击后似乎没有被正确替换。相反,具有新背景颜色的无样式框(无边框半径等)覆盖了默认背景颜色(视觉上很明显)。我很想知道为什么会这样。有人可以启发我吗?这是一个已知的现象吗?还是与我的活动和 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) && !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>

标签: javascripthtmlcssevents

解决方案


那是因为您正在设置background-coloron e.targetwhich 可能不是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) && !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>


推荐阅读