j roc
j roc

Reputation: 238

function inside a function not executing

Sorry for the poor title, I wasn't sure how to properly phrase it

This is for a Tic Tac Toe game I'm trying to build -

I'm trying to call my set() inside of my reset(), so that every time the #reset button is clicked, the next click on the container displays 'X'.

Right now it works for the first two clicks, and when I pass the function into the HTML button tag it works three times, but then the next click displays 'O'. I need it to work every time, because when you reset the game it should be 'Player 1's turn', which displays 'X' on the container

#heads {
    padding-top: 30px;
    text-align: center;
    font-size: 30px;
    color: rgb(46, 46, 46);
}

#container {
    text-align: center;
    margin-top: 20px;
    display: grid;
    grid-template-columns: 1fr 1fr 1fr;
    grid-template-rows: 1fr 1fr 1fr;
    width: 300px;
    height: 300px;
    background-color: rgb(46, 46, 46);
    border: 1px solid  rgb(255, 255, 255);
}

#container div {
    font-size: 25px;
    border: 2px solid rgb(255, 255, 255);
    color: white;
    text-align: center;
    padding-top: 35px;
}

#container div:hover {
    background-color:rgb(58, 58, 58);
}

#reset {
    margin-top: 10px;
    background-color: rgb(46, 46, 46);
    color: white;
    border-radius: 3px;
    outline: none;
}

#reset:hover {
   background-color:  rgb(58, 58, 58);
}

#divone {
    font-size: 18px;
    margin-top: 15px;
    color: rgb(46, 46, 46);
}

#divtwo {
    display: none;
    font-size: 18px;
    margin-top: 15px;
    color: rgb(46, 46, 46);
}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <link href="./style.css" type="text/css" rel="stylesheet">
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>    <title>Tic Tac Toe </title>
</head>
<body>

<header id="heads">TIC TAC TOE</header>
<center>
<div id="divone">PLAYER 1's TURN</div>
<div id="divtwo">PLAYER 2's TURN</div>
</center>


 <center>   
<div id="container">


</div>
</center>

<center>
<button id="reset">RESET GAME</button>
</center>


</body>

<script>
const container = document.querySelector('#container')
gameBoard = ['', '', '', '', '', '', '', '', '']

// creates divs for gameboard
let html = '';
for (var i = 0; i <= 8; i++) {
    html += '<div class="letters">' + gameBoard[i] + '</div>';
}
container.innerHTML += html;


// object constructors 
function Player1(name) {
    this.name = name
    this.one = function () {
        event.target.textContent = 'X'
        let x = document.getElementById('playertwo')
    }
}
function Player2(name) {
    this.name = name
    this.two = function () {
        event.target.textContent = 'O'
    }
}

let bop = new Player1('bop')
let bob = new Player2('bob')


// toggles between player 1 and player 2 functions to mark the table
function set() {
    $('#container').click(function () {
        var clicks = $(this).data('clicks');
        if (clicks) {
            bob.two()
        } else {
            bop.one()
        }
        $(this).data("clicks", !clicks);
    });
}
set()


// 'reset game' button, clears table, sets 'player 1's turn', and makes the next click 'X'
function reset(){
document.querySelector('#reset').addEventListener("click", () => {


    set()

    container.innerHTML = html;

    document.querySelector('#divone').style.display = 'block'
    document.querySelector('#divtwo').style.display = 'none'

})
}
reset()


// display whos turn it is
container.addEventListener('click', () => {
    if (document.getElementById('divone')) {

        if (document.getElementById('divone').style.display == 'none') {
            document.getElementById('divone').style.display = 'block';
            document.getElementById('divtwo').style.display = 'none';
        }
        else {
            document.getElementById('divone').style.display = 'none';
            document.getElementById('divtwo').style.display = 'block';
        }
    }

})
</script>
</html>

Thank you for any help!

Upvotes: 0

Views: 56

Answers (1)

cdoshi
cdoshi

Reputation: 2832

The issue is the set function itself. When you keep calling the set function, it keeps adding multiple event listeners to the container. Thus, when you click on the box, it triggers multiple events for a single click. Instead attach an event listener once and just set the correct data attribute on reset like in the snippet below

#heads {
    padding-top: 30px;
    text-align: center;
    font-size: 30px;
    color: rgb(46, 46, 46);
}

#container {
    text-align: center;
    margin-top: 20px;
    display: grid;
    grid-template-columns: 1fr 1fr 1fr;
    grid-template-rows: 1fr 1fr 1fr;
    width: 300px;
    height: 300px;
    background-color: rgb(46, 46, 46);
    border: 1px solid  rgb(255, 255, 255);
}

#container div {
    font-size: 25px;
    border: 2px solid rgb(255, 255, 255);
    color: white;
    text-align: center;
    padding-top: 35px;
}

#container div:hover {
    background-color:rgb(58, 58, 58);
}

#reset {
    margin-top: 10px;
    background-color: rgb(46, 46, 46);
    color: white;
    border-radius: 3px;
    outline: none;
}

#reset:hover {
   background-color:  rgb(58, 58, 58);
}

#divone {
    font-size: 18px;
    margin-top: 15px;
    color: rgb(46, 46, 46);
}

#divtwo {
    display: none;
    font-size: 18px;
    margin-top: 15px;
    color: rgb(46, 46, 46);
}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <link href="./style.css" type="text/css" rel="stylesheet">
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>    <title>Tic Tac Toe </title>
</head>
<body>

<header id="heads">TIC TAC TOE</header>
<center>
<div id="divone">PLAYER 1's TURN</div>
<div id="divtwo">PLAYER 2's TURN</div>
</center>


 <center>   
<div id="container">


</div>
</center>

<center>
<button id="reset">RESET GAME</button>
</center>


</body>

<script>
const container = document.querySelector('#container')
gameBoard = ['', '', '', '', '', '', '', '', '']

// creates divs for gameboard
let html = '';
for (var i = 0; i <= 8; i++) {
    html += '<div class="letters">' + gameBoard[i] + '</div>';
}
container.innerHTML += html;


// object constructors 
function Player1(name) {
    this.name = name
    this.one = function () {
        event.target.textContent = 'X'
        let x = document.getElementById('playertwo')
    }
}
function Player2(name) {
    this.name = name
    this.two = function () {
        event.target.textContent = 'O'
    }
}

let bop = new Player1('bop')
let bob = new Player2('bob')


// toggles between player 1 and player 2 functions to mark the table

    $('#container').click(function () {
        var clicks = $(this).data('clicks');
        console.log(this, $(this).data("clicks"));
        if (clicks) {
        console.log('two called');
            bob.two()
        } else {
                console.log('one called');
            bop.one()
        }
        $(this).data("clicks", !clicks);
    });




// 'reset game' button, clears table, sets 'player 1's turn', and makes the next click 'X'
function reset(){
document.querySelector('#reset').addEventListener("click", () => {


$('#container').data("clicks", false);

    container.innerHTML = html;

    document.querySelector('#divone').style.display = 'block'
    document.querySelector('#divtwo').style.display = 'none'

})
}
reset()


// display whos turn it is
container.addEventListener('click', () => {
    if (document.getElementById('divone')) {

        if (document.getElementById('divone').style.display == 'none') {
            document.getElementById('divone').style.display = 'block';
            document.getElementById('divtwo').style.display = 'none';
        }
        else {
            document.getElementById('divone').style.display = 'none';
            document.getElementById('divtwo').style.display = 'block';
        }
    }

})
</script>
</html>

Upvotes: 1

Related Questions