Почему не удаляются слушатели событий - PullRequest
0 голосов
/ 27 мая 2020

document.getElementsByClassName('restart')[0].addEventListener('click', init);
var tiles = document.querySelectorAll('.row div');
let bombTile = [];

init();


 function clickHand(tile, index) {
    if (bombTile.indexOf(index) !== -1) {
        bombClicked(tile , index);
    } else {
        flipMe(tile, index);
    }
}


function bombClicked(tile ,index) {
    tile.classList.add('bomb');
    bombTile.forEach(e => {
        tiles[e].classList.add('bomb');
        tiles[e].innerHTML = '<i class="fas fa-bomb"></i>';
    })
    document.getElementsByClassName('row')[0].classList.add('bombed');
    
}

function flipMe(tile , index) {
    tile.classList.add('active');
    tile.innerHTML = '<i class="fas fa-sun"></i>';
    tile.removeEventListener('click' , clickHand);
}


function init() {
    bombTile = []
    while (bombTile.length < 10) {
        var r = Math.floor(Math.random() * 80) + 1;
        if (bombTile.indexOf(r) === -1) bombTile.push(r);
    }
    document.getElementsByClassName('row')[0].classList.remove('bombed')
    tiles.forEach((tile, index) => {
        tile.addEventListener('click',  clickHand.bind(this,tile , index));
        tile.className = '';
        tile.innerHTML = '';

    })
}
*{
    padding: 0;
    margin: 0;
}

body{
    display: flex;
    justify-content: center;
    flex-direction: column;
    background-image: linear-gradient(to right, rgba(233,233,233,.9), rgba(0,0,0,.8)) , url("https://images5.alphacoders.com/540/thumb-1920-540654.jpg");
    background-size: cover;
    align-items: center;
    font-family: 'Montserrat', sans-serif;
    min-height: 100vh;
}

.row{
    width: 540px;
    display: flex;
    flex-wrap: wrap;
    box-shadow:0 2px 4px rgba(0,0,0,.8);
}

.row.bombed{
    animation: shake 0.82s cubic-bezier(.36,.07,.19,.97) both;
    transform: translate3d(0, 0, 0);
    backface-visibility: hidden;
}

h1{
    margin-bottom: 20px;
    font-weight: 300;
}

.row div{
    display: flex;
    justify-content: center;
    box-sizing: border-box;
    align-items: center;
    width: 60px;
    height: 60px;
    background: rgba(200,200,200,.8);
    border: 1px solid #000;

    transition: all .3s ease;

}

.row div.active{
    transform: rotateY(180deg);
    background-color: #000;
}

.row div.active i{
    color: yellow;
    font-size: 30px;
}

.row div.bomb{
    transform: rotateY(180deg);
    background: #f00;
    font-size: 20px;
}


.restart:link,
.restart:visited{
    text-decoration: none;
    text-transform: uppercase;
    padding: 10px 15px;
    display: inline-block;
    margin: 20px 0;
    border: 1px solid #fff;
    color: white;
    transition: all .3s ease;
}

.restart:hover{
    border: 1px solid #fff;
    background-color: white;
    color: black;
}

@keyframes shake {
    10%, 90% {
      transform: translate3d(-1px, 0, 0);
    }
    
    20%, 80% {
      transform: translate3d(2px, 0, 0);
    }
  
    30%, 50%, 70% {
      transform: translate3d(-4px, 0, 0);
    }
  
    40%, 60% {
      transform: translate3d(4px, 0, 0);
    }
  }
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Bomber</title>
    <link href="https://fonts.googleapis.com/css2?family=Montserrat:wght@400;500;600;700&display=swap" rel="stylesheet">
    <link rel="stylesheet" href="style.css">
    <script src="https://kit.fontawesome.com/f80fd99102.js" crossorigin="anonymous"></script>
</head>
<body> 
    <h1>
        Bomber
    </h1>
    <div class="bomber-grid">
        <div class="row">
            <div></div>
            <div></div>
            <div></div>
            <div></div>
            <div></div>
            <div></div>
            <div></div>
            <div></div>
            <div></div>
            <div></div>
            <div></div>
            <div></div>
            <div></div>
            <div></div>
            <div></div>
            <div></div>
            <div></div>
            <div></div>
            <div></div>
            <div></div>
            <div></div>
            <div></div>
            <div></div>
            <div></div>
            <div></div>
            <div></div>
            <div></div>
            <div></div>
            <div></div>
            <div></div>
            <div></div>
            <div></div>
            <div></div>
            <div></div>
            <div></div>
            <div></div>
            <div></div>
            <div></div>
            <div></div>
            <div></div>
            <div></div>
            <div></div>
            <div></div>
            <div></div>
            <div></div>
            <div></div>
            <div></div>
            <div></div>
            <div></div>
            <div></div>
            <div></div>
            <div></div>
            <div></div>
            <div></div>
            <div></div>
            <div></div>
            <div></div>
            <div></div>
            <div></div>
            <div></div>
            <div></div>
            <div></div>
            <div></div>
            <div></div>
            <div></div>
            <div></div>
            <div></div>
            <div></div>
            <div></div>
            <div></div>
            <div></div>
            <div></div>
            <div></div>
            <div></div>
            <div></div>
            <div></div>
            <div></div>
            <div></div>
            <div></div>
            <div></div>
            <div></div>
        </div>
    </div>
    <a href="#!" class="restart">
        New Game
    </a>
    <script src="index.js"></script>
</body>
</html>

Это простая игра с бомбардировщиком, в которой на 10 плитках есть бомба. Когда пользователь щелкает, игра заканчивается.

В чем моя проблема, когда я нажимаю на любую плитку, я хочу удалить прикрепленное к ней прослушивание событий. Если пользователь нажимает на плитку с бомбой, я хочу удалить прослушиватель событий с каждой плитки.

Я добавил код для удаления прослушивателя событий, но он почему-то не работает.

Ответы [ 2 ]

1 голос
/ 27 мая 2020

Чтобы удалить прослушиватель событий, вы должны передать такую ​​же функцию в removeEventListener, которую вы передаете addEventListener.

tile.removeEventListener('click' , clickHand);

tile.addEventListener('click',  clickHand.bind(this,tile , index));

Вы пытается удалить clickHand, но вы добавили новую функцию, сгенерированную вызовом bind на clickHand.

Более простым подходом для этого, вероятно, было бы изменить clickHand, чтобы он проверил состояние плитки и определил, был ли он уже нажат (и затем вернулся, не делая ничего другого, если это было).

0 голосов
/ 27 мая 2020

Причина, по которой removeListener может не работать, заключается в том, что вы создаете новую функцию каждый раз, когда используете .bind. RemoveEventListener ожидает ту же функцию, которая используется в качестве обработчика в addEventListener.

То, что вы делаете,

tile.addEventListener('click',  clickHand.bind(this,tile , index));

Таким образом, вы не можете удалить, используя

tile.removeEventListener('click',  clickHand);

Чтобы правильно удалить его, сделайте что-то вроде этого:

let tileHandler =  clickHand.bind(this,tile , index)
tile.addEventListener('click',  tileHandler);

// Then remove by
tile.removeEventListener('click',  tileHandler);

Но тайлов много, и вам нужно вести запись для каждого нового созданного обработчика. Итак, что вы можете сделать, так это установить флажок, окончена игра или нет. И если это так, то предотвращайте переворачивание плиток.

Добавьте флаг

let gameOver;

В вашей функции щелчка

else if(!gameOver){
        flipMe(tile, index);
    }
}

И в вашей bombClicked() функции добавить,

gameOver=true;

document.getElementsByClassName('restart')[0].addEventListener('click', init);
var tiles = document.querySelectorAll('.row div');
let bombTile = [];
let gameOver = false;
init();


 function clickHand(tile, index) {
    if (bombTile.indexOf(index) !== -1) {
        bombClicked(tile , index);
    } else if(!gameOver){
        flipMe(tile, index);
    }
}


function bombClicked(tile ,index) {
    gameOver=true;
    tile.classList.add('bomb');
    bombTile.forEach(e => {
        tiles[e].classList.add('bomb');
        tiles[e].innerHTML = '<i class="fas fa-bomb"></i>';
    })
    document.getElementsByClassName('row')[0].classList.add('bombed');
    
}

function flipMe(tile , index) {
    tile.classList.add('active');
    tile.innerHTML = '<i class="fas fa-sun"></i>';
    tile.removeEventListener('click' , clickHand);
}


function init() {
    bombTile = []
    while (bombTile.length < 10) {
        var r = Math.floor(Math.random() * 80) + 1;
        if (bombTile.indexOf(r) === -1) bombTile.push(r);
    }
    document.getElementsByClassName('row')[0].classList.remove('bombed')
    tiles.forEach((tile, index) => {
        tile.addEventListener('click',  clickHand.bind(this,tile , index));
        tile.className = '';
        tile.innerHTML = '';

    })
}
*{
    padding: 0;
    margin: 0;
}

body{
    display: flex;
    justify-content: center;
    flex-direction: column;
    background-image: linear-gradient(to right, rgba(233,233,233,.9), rgba(0,0,0,.8)) , url("https://images5.alphacoders.com/540/thumb-1920-540654.jpg");
    background-size: cover;
    align-items: center;
    font-family: 'Montserrat', sans-serif;
    min-height: 100vh;
}

.row{
    width: 540px;
    display: flex;
    flex-wrap: wrap;
    box-shadow:0 2px 4px rgba(0,0,0,.8);
}

.row.bombed{
    animation: shake 0.82s cubic-bezier(.36,.07,.19,.97) both;
    transform: translate3d(0, 0, 0);
    backface-visibility: hidden;
}

h1{
    margin-bottom: 20px;
    font-weight: 300;
}

.row div{
    display: flex;
    justify-content: center;
    box-sizing: border-box;
    align-items: center;
    width: 60px;
    height: 60px;
    background: rgba(200,200,200,.8);
    border: 1px solid #000;

    transition: all .3s ease;

}

.row div.active{
    transform: rotateY(180deg);
    background-color: #000;
}

.row div.active i{
    color: yellow;
    font-size: 30px;
}

.row div.bomb{
    transform: rotateY(180deg);
    background: #f00;
    font-size: 20px;
}


.restart:link,
.restart:visited{
    text-decoration: none;
    text-transform: uppercase;
    padding: 10px 15px;
    display: inline-block;
    margin: 20px 0;
    border: 1px solid #fff;
    color: white;
    transition: all .3s ease;
}

.restart:hover{
    border: 1px solid #fff;
    background-color: white;
    color: black;
}

@keyframes shake {
    10%, 90% {
      transform: translate3d(-1px, 0, 0);
    }
    
    20%, 80% {
      transform: translate3d(2px, 0, 0);
    }
  
    30%, 50%, 70% {
      transform: translate3d(-4px, 0, 0);
    }
  
    40%, 60% {
      transform: translate3d(4px, 0, 0);
    }
  }
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Bomber</title>
    <link href="https://fonts.googleapis.com/css2?family=Montserrat:wght@400;500;600;700&display=swap" rel="stylesheet">
    <link rel="stylesheet" href="style.css">
    <script src="https://kit.fontawesome.com/f80fd99102.js" crossorigin="anonymous"></script>
</head>
<body> 
    <h1>
        Bomber
    </h1>
    <div class="bomber-grid">
        <div class="row">
            <div></div>
            <div></div>
            <div></div>
            <div></div>
            <div></div>
            <div></div>
            <div></div>
            <div></div>
            <div></div>
            <div></div>
            <div></div>
            <div></div>
            <div></div>
            <div></div>
            <div></div>
            <div></div>
            <div></div>
            <div></div>
            <div></div>
            <div></div>
            <div></div>
            <div></div>
            <div></div>
            <div></div>
            <div></div>
            <div></div>
            <div></div>
            <div></div>
            <div></div>
            <div></div>
            <div></div>
            <div></div>
            <div></div>
            <div></div>
            <div></div>
            <div></div>
            <div></div>
            <div></div>
            <div></div>
            <div></div>
            <div></div>
            <div></div>
            <div></div>
            <div></div>
            <div></div>
            <div></div>
            <div></div>
            <div></div>
            <div></div>
            <div></div>
            <div></div>
            <div></div>
            <div></div>
            <div></div>
            <div></div>
            <div></div>
            <div></div>
            <div></div>
            <div></div>
            <div></div>
            <div></div>
            <div></div>
            <div></div>
            <div></div>
            <div></div>
            <div></div>
            <div></div>
            <div></div>
            <div></div>
            <div></div>
            <div></div>
            <div></div>
            <div></div>
            <div></div>
            <div></div>
            <div></div>
            <div></div>
            <div></div>
            <div></div>
            <div></div>
            <div></div>
        </div>
    </div>
    <a href="#!" class="restart">
        New Game
    </a>
    <script src="index.js"></script>
</body>
</html>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...