Ошибка при нажатии на родительский элемент срабатывает событие дочернего

Всем здравствуйте, столкнулся с ошибкой при создании игры в 21.
Добавил див и добавил к нему addEventListener, но когда нажимаю на body или другой блок, то вызывается событие которое на диве. В чём проблема не знаю, как сделать так чтобы при нажатии только на див обработчик начинал работать. Добавлял также к диву event.stoppropagation() не помогло.
Мой код:
Js:

//Make a function
function CardGame() {
    //Define variables
    this.cardDeck = 36;
    this.cardNumbers = [];
    this.cardBack = null;
    this.getCard = null;
    this.passButton = null;
    this.myScore = null;
    this.opponentScore = null;
    this.opponentCards = null;
    var myHand = 0;
    var opponentHand = 0;
    ///Start function
    this.start = function () {
        //Write in array amount of cards from 1 to 36
        for (var i = 1; i < this.cardDeck; i++) {
            var x = this.cardNumbers.push(Math.floor(Math.random() * this.cardDeck));
            x = this.cardNumbers[i]
        };
        console.log(this.cardNumbers);
        //call function and transfer values
        uniq_fast(this.cardNumbers);
        //function which mix a values of arr in different order
        function uniq_fast(a) {
            var seen = {};
            var out = [];
            var len = a.length;
            var j = 1;
            for (var i = 1; i < len; i++) {
                var item = a[i];
                if (seen[item] !== 1) {
                    seen[item] = 1;
                    out[j++] = item;
                }
                if (out.length < 36) {
                    out.push(Math.floor(Math.random() * 36));
                }
            }
            for(var x=1;x<out.length;x++){
                var wrapper = document.getElementById('wrapper');
                wrapper.innerHTML = wrapper.innerHTML + '<div id = '+ out[x] +' class=no-card ><img src=./img/back-size-of-card.jpg /></div>' 
            }
        }
        //add listeners to their selectors
        this.cardBack = document.querySelector('.no-card');
        console.log(this.cardBack);
        this.cardBack = addEventListener('click',function (e){
            e.stopPropagation()
            onCardClick();
        });

        this.passButton = document.querySelector('#pass-card-button');
        this.passButton.addEventListener('click', function(e){
            onPassClick();
        })
    };
    //function when user click on deck and cards are turn around
    function onCardClick(event){
        this.myScore = document.getElementById('my-score');
        this.getCard = document.getElementsByClassName('no-card');
        var cardId = this.getCard[this.getCard.length-1].id;
        this.getCard[this.getCard.length-1].innerHTML = '<img src = ./img/'+cardId+'.jpg />'
        this.getCard[this.getCard.length-1].className = 'my-card';
        var number = orderCardIds(cardId);
        myHand = myHand+number;
        this.myScore.innerHTML = myHand;
        if(myHand==21){
            alert('You are real Black Jack :)');
        }else if(myHand > 21){
            alert('You lose? you have above 21 :(');
        }
    };
    //function when user click on pass and opponent make a move
    function onPassClick(){
        this.opponentScore = document.getElementById('opponent-score');
        this.getCard = document.getElementsByClassName('no-card');
        var cardId = this.getCard[this.getCard.length-1].id;
        this.getCard[this.getCard.length-1].innerHTML = '<img src = ./img/'+cardId+'.jpg />'
        this.getCard[this.getCard.length-1].className = 'opponent-card';
        var number = orderCardIds(cardId);
        opponentHand = opponentHand+number;
        this.opponentScore.innerHTML =  opponentHand;
        if(opponentHand==21){
            alert('You have beaten');
        }else if(opponentHand > 21){
            alert('You are real Monster');
        }
    };
    //function that returns cardId for another functions
    function orderCardIds(cardId){
        if(cardId == '1'||cardId == '2' ||cardId == '3' || cardId == '4'){
            cardId = 6;
        }else if(cardId == '5' ||cardId == '6' ||cardId == '7' || cardId == '8'){
            cardId =7;
        }else if(cardId == '9' ||cardId == '10' ||cardId == '11' || cardId == '12'){
            cardId = 8;
        }else if(cardId == '13' ||cardId == '14' ||cardId == '15' || cardId == '16'){
            cardId = 9;
        }else if(cardId == '17' ||cardId == '18' ||cardId == '19' || cardId == '20'){
            cardId = 10;
        }else if(cardId == '21'||cardId == '22' ||cardId == '23' || cardId == '24'){
            cardId = 2;
        }else if(cardId == '25'||cardId == '26'||cardId == '27' || cardId == '28'){
            cardId =3;
        }else if(cardId == '29' ||cardId == '30' ||cardId == '31' || cardId == '32'){
            cardId = 4;
        }else if(cardId == '33' ||cardId == '34' ||cardId == '35' || cardId == '36' ){
            cardId = 11;
        }
        return cardId;
    }
}

var cardGame1 = new CardGame();
cardGame1.start();

HTML:

<div class="wrapper" id="wrapper">
        <span id="opponent-score">0</span>
        <span id="my-score">0</span>
        <button id="pass-card-button" class="pass-card-button">Pass</button>
    </div>

Помогите пожалуйста

Похоже что тут происходит не то что нужно. addEventListener вызывается не на объекта, глобально, и наверняка срабатывает как метод window. Попробуй поменять this.cardBack = addEventListener на this.cardBack.addEventListener

Теперь мой код выглядит так :

//Make a function
function CardGame() {
    //Define variables
    this.cardDeck = 36;
    this.cardNumbers = [];
    this.cardBack = null;
    this.getCard = null;
    this.passButton = null;
    this.myScore = null;
    this.opponentScore = null;
    this.opponentCards = null;
    var myHand = 0;
    var opponentHand = 0;
    ///Start function
    this.start = function () {
        //Write in array amount of cards from 1 to 36
        for (var i = 1; i < this.cardDeck; i++) {
            var x = this.cardNumbers.push(Math.floor(Math.random() * this.cardDeck));
            x = this.cardNumbers[i]
        };
        console.log(this.cardNumbers);
        //call function and transfer values
        uniq_fast(this.cardNumbers);
        //function which mix a values of arr in different order
        function uniq_fast(a) {
            var seen = {};
            var out = [];
            var len = a.length;
            var j = 1;
            for (var i = 1; i < len; i++) {
                var item = a[i];
                if (seen[item] !== 1) {
                    seen[item] = 1;
                    out[j++] = item;
                }
                if (out.length < 36) {
                    out.push(Math.floor(Math.random() * 36));
                }
            }
            for(var x=1;x<out.length;x++){
                var wrapper = document.getElementById('wrapper');
                wrapper.innerHTML = wrapper.innerHTML + '<div id = '+ out[x] +' class=no-card ><img src=./img/back-size-of-card.jpg /></div>' 
            }
        }
        //add listeners to their selectors
        this.cardBack = document.querySelector('.no-card');
        console.log(this.cardBack);
        this.cardBack = this.cardBack.addEventListener('click',function (e){
            onCardClick();
        });

        this.passButton = document.querySelector('#pass-card-button');
        this.passButton.addEventListener('click', function(e){
            onPassClick();
        })
    };
    //function when user click on deck and cards are turn around
    function onCardClick(){
        this.myScore = document.getElementById('my-score');
        this.getCard = document.getElementsByClassName('no-card');
        var cardId = this.getCard[this.getCard.length-1].id;
        this.getCard[this.getCard.length-1].innerHTML = '<img src = ./img/'+cardId+'.jpg />'
        this.getCard[this.getCard.length-1].className = 'my-card';
        var number = orderCardIds(cardId);
        myHand = myHand+number;
        this.myScore.innerHTML = myHand;
        if(myHand==21){
            alert('You are real Black Jack :)');
        }else if(myHand > 21){
            alert('You lose? you have above 21 :(');
        }
    };
    //function when user click on pass and opponent make a move
    function onPassClick(){
        this.opponentScore = document.getElementById('opponent-score');
        this.getCard = document.getElementsByClassName('no-card');
        var cardId = this.getCard[this.getCard.length-1].id;
        this.getCard[this.getCard.length-1].innerHTML = '<img src = ./img/'+cardId+'.jpg />'
        this.getCard[this.getCard.length-1].className = 'opponent-card';
        var number = orderCardIds(cardId);
        opponentHand = opponentHand+number;
        this.opponentScore.innerHTML =  opponentHand;
        if(opponentHand==21){
            alert('You have beaten');
        }else if(opponentHand > 21){
            alert('You are real Monster');
        }
    };
    //function that returns cardId for another functions
    function orderCardIds(cardId){
        if(cardId == '1'||cardId == '2' ||cardId == '3' || cardId == '4'){
            cardId = 6;
        }else if(cardId == '5' ||cardId == '6' ||cardId == '7' || cardId == '8'){
            cardId =7;
        }else if(cardId == '9' ||cardId == '10' ||cardId == '11' || cardId == '12'){
            cardId = 8;
        }else if(cardId == '13' ||cardId == '14' ||cardId == '15' || cardId == '16'){
            cardId = 9;
        }else if(cardId == '17' ||cardId == '18' ||cardId == '19' || cardId == '20'){
            cardId = 10;
        }else if(cardId == '21'||cardId == '22' ||cardId == '23' || cardId == '24'){
            cardId = 2;
        }else if(cardId == '25'||cardId == '26'||cardId == '27' || cardId == '28'){
            cardId =3;
        }else if(cardId == '29' ||cardId == '30' ||cardId == '31' || cardId == '32'){
            cardId = 4;
        }else if(cardId == '33' ||cardId == '34' ||cardId == '35' || cardId == '36' ){
            cardId = 11;
        }
        return cardId;
    }
}

var cardGame1 = new CardGame();
cardGame1.start();

Теперь на любой клик не срабатывает событие, хотя на кнопку событие работает

Не достаточно информации чтобы понять.

Напиши пожалуйста в формате “что ожидаешь увидеть” и “что видишь”.

Дай код который отвечает за “срабатывание события” и который ты ожидаешь что выполнится. А так же опиши условия при которых код должен срабатывать (например при клике на кнопке с классом X).

Я создаю с помощью цикла и функции код который будет возвращать массив с цифрами от 1 до 36, после будет перемешивать его и создавать дивки с id цифры из массива: for (var i = 1; i < this.cardDeck; i++) {
var x = this.cardNumbers.push(Math.floor(Math.random() * this.cardDeck));
x = this.cardNumbers[i]
};
console.log(this.cardNumbers);
//call function and transfer values
uniq_fast(this.cardNumbers);
//function which mix a values of arr in different order
function uniq_fast(a) {
var seen = {};
var out = [];
var len = a.length;
var j = 1;
for (var i = 1; i < len; i++) {
var item = a[i];
if (seen[item] !== 1) {
seen[item] = 1;
out[j++] = item;
}
if (out.length < 36) {
out.push(Math.floor(Math.random() * 36));
}
}
for(var x=1;x<out.length;x++){
var wrapper = document.getElementById(‘wrapper’);
wrapper.innerHTML = wrapper.innerHTML + ‘


}
}
На див вешается событие которое должно вызвать(оно не работает):
this.cardBack = document.querySelector(‘.no-card’);
console.log(this.cardBack);
this.cardBack = this.cardBack.addEventListener(‘click’,function (e){
onCardClick();
});
Когда событие вызовется карта должно поменять класс и ссылку на изображении, также отобразить количество очков в зависимости какая карта выпадет : function onCardClick(){
this.myScore = document.getElementById(‘my-score’);
this.getCard = document.getElementsByClassName(‘no-card’);
var cardId = this.getCard[this.getCard.length-1].id;
this.getCard[this.getCard.length-1].innerHTML = ‘<img src = ./img/’+cardId+‘.jpg />’
this.getCard[this.getCard.length-1].className = ‘my-card’;
var number = orderCardIds(cardId);
myHand = myHand+number;
this.myScore.innerHTML = myHand;
if(myHand==21){
alert(‘You are real Black Jack :)’);
}else if(myHand > 21){
alert(‘You lose? you have above 21 :(’);
}
};
Когда событие срабатывает то оно вызовет функцию которая сверит id с предложенным номером и если номер совпадает то подставиться нужное число например если id =1 то подставиться число 6, это для того чтобы вписать нужное количество очков:function orderCardIds(cardId){
if(cardId == ‘1’||cardId == ‘2’ ||cardId == ‘3’ || cardId == ‘4’){
cardId = 6;
}else if(cardId == ‘5’ ||cardId == ‘6’ ||cardId == ‘7’ || cardId == ‘8’){
cardId =7;
}else if(cardId == ‘9’ ||cardId == ‘10’ ||cardId == ‘11’ || cardId == ‘12’){
cardId = 8;
}else if(cardId == ‘13’ ||cardId == ‘14’ ||cardId == ‘15’ || cardId == ‘16’){
cardId = 9;
}else if(cardId == ‘17’ ||cardId == ‘18’ ||cardId == ‘19’ || cardId == ‘20’){
cardId = 10;
}else if(cardId == ‘21’||cardId == ‘22’ ||cardId == ‘23’ || cardId == ‘24’){
cardId = 2;
}else if(cardId == ‘25’||cardId == ‘26’||cardId == ‘27’ || cardId == ‘28’){
cardId =3;
}else if(cardId == ‘29’ ||cardId == ‘30’ ||cardId == ‘31’ || cardId == ‘32’){
cardId = 4;
}else if(cardId == ‘33’ ||cardId == ‘34’ ||cardId == ‘35’ || cardId == ‘36’ ){
cardId = 11;
}
return cardId;
}
Если не достаточно могу попробовать ещё расписать

1 лайк

Из описания не понятно какая из описанной части не работает как ожидается.

Я предположу что ты ожидаешь что код

this.cardBack = document.querySelector('.no-card');
this.cardBack = this.cardBack.addEventListener('click',function (e){
    onCardClick();
});

навесит обработчик события на все элементы с классом .no-card. Такие ожидания?

На див вешается событие которое должно вызвать(оно не работает):
this.cardBack = document.querySelector(‘.no-card’);
console.log(this.cardBack);
this.cardBack = this.cardBack.addEventListener(‘click’,function (e){
onCardClick();
})

1 лайк

Да, ожидания такие

Написанный код навесит обработчик события только 1 первый элемент (можно убедиться, кликнув на первую карточку). Чтобы навесить на все нужно использовать querySelectorAll, пробежаться по результируюему массивоподобному объекту и навесить обработчик на каждый элемент.

Получилось решить, также после появилась ошибка что this.cardBack.addEventListener is not a function. Я решил ошибку тем что сделал цикл for (const cardBack of this.cardBack) {
cardBack.addEventListener(‘click’, function() {
onCardClick();
});
}
Спасибо огромное за помощь !!!

1 лайк

Пожалуйста.

Эту тему я помечаю как решенную, давай в ней не общение. Если будет еще вопрос формата “вопрос-ответ” создавай новую тему в разделе Вопрос-ответ пожалуйста. Если будет вопрос формата обсуждения (к чему мы в итоге пришли в этому формату общения) создавай новую тему в разделе “обсуждения”.