Click here to Skip to main content
15,886,919 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
First of all, have a look at the full code:
JavaScript
let turn='X';
let isover=false;
// changing the turn
const change=()=>{
    return turn==='X'?'O':'X';
}
// check win
const check=()=>{
    let boxtext=document.getElementsByClassName('btext');
    let  wins = [
        [0,1,2],[3,4,5],[6,7,8],[0,3,6],[1,4,7],[2,5,8],[0,4,8],[2,4,6]
    ]
    wins.forEach((e)=>{
        if((boxtext[e[0]].innerText === boxtext[e[1]].innerText)&& 
          (boxtext[e[1]].innerText === boxtext[e[2]].innerText)&& 
          (boxtext[e[0]].innerText !== '')){
            document.querySelector('.info').innerText = 
                     `'${boxtext[e[0]].innerText}'  WON`;
            isover=true;
            document.querySelector('.info').style.color= 'rgb(142, 2, 109)';
            document.querySelector('.info').style.fontWeight='bold';
            let boxes=document.getElementsByClassName('box');
            Array.from(boxes).forEach(element=>{
            let boxtext=element.querySelector('.btext');
            element.removeEventListener('click',play(boxtext))
            })
        }
    })
}
// logic
let boxes=document.getElementsByClassName('box');
Array.from(boxes).forEach(element=>{
    let boxtext=element.querySelector('.btext');
    element.addEventListener('click',()=>play(boxtext))
    document.querySelector('#reset').addEventListener('click',()=>{
        boxtext.innerText='';
        turn='X';
        isover=false;
        document.getElementsByClassName('info')[0].innerText= turn+"'s turn";
        document.querySelector('.info').style.color= 'black';
        document.querySelector('.info').style.fontWeight='100';
    })
})
function play(boxtext) {
    if (boxtext.innerText === '') {
        boxtext.innerText = turn;
        turn = change();
        check();
        if (!isover) {
            document.getElementsByClassName('info')[0].innerText = turn + "'s turn";
        }
    }
}

I want to remove an event listener in a typical case where it is connected to an outer scope.

What I have tried:

I somehow figured it out that 'removeEventListener dosen't work with anonymous function'.
For example:
JavaScript
let btn=document.querySelector('.btn');
    btn.addEventListener('click',play);
    btn.addEventListener('keypress',play);
    function play(e){
        console.log(e)
        sum(4,5)
    }
    function sum(a,b){
        console.log(a+b)
    }
    setTimeout(()=>{
        console.log('removed')
        btn.removeEventListener('keypress',play)
    },5000)

But I'm unable to make this thing happen in the above given code.
Posted
Updated 24-Oct-23 11:06am
v2

Quote:
JavaScript
element.removeEventListener('click',play(boxtext))
Breaking that line down, you want to remove a listener for the click event on the specified element. The listener you want to remove is the function returned from the play(boxtext) call.

But your play function doesn't return a function, so there is no listener to remove.

The simpler option would be to use event delegation[^], and test the isover variable at the start of the handler. For example:
JavaScript
document.addEventListener("click", (e) => {
    if (isover) { return; }
    
    let box = e.target;
    if (!box.classList.contains("box")) { box = box.closest(".box"); }
    if (!box) { return; }
    
    const boxtext = box.querySelector(".btext");
    if (!boxtext) { return; }
    
    play(boxtext);
});

document.getElementById("reset").addEventListener("click", () => {
    turn = "X";
    isover = false;
    document.querySelectorAll(".btext").forEach(boxtext => boxtext.innerText = "");
    
    const info = document.querySelector(".info");
    info.innerText = `${turn}'s turn`;
    info.style.color= 'black';
    info.style.fontWeight='100';
});

const check = () => {
    const wins = [
        [0,1,2], [3,4,5], [6,7,8], [0,3,6], [1,4,7], [2,5,8], [0,4,8], [2,4,6]
    ];

    const boxtext = document.getElementsByClassName("btext");
    for (const win of wins) {
        const t0 = boxtext[win[0]].innerText;
        const t1 = boxtext[win[1]].innerText;
        const t2 = boxtext[win[2]].innerText;
        if (t0 !== "" && t0 === t1 && t0 === t2) {
            isOver = true;
            const info = document.querySelector(".info");
            info.innerText = `${t0} WON`;
            info.style.color = 'rgb(142, 2, 109)';
            info.style.fontWeight = 'bold';
            return;
        }
    }
};
 
Share this answer
 
When it comes to removing event listeners, I understand it to be a very strange aspect of JavaScript. When I need to remove an existing event listener, the most effective way to be sure that it's removed is to create a cloned node of the element that the event listener is assigned to. Remove the original target element from the DOM, and replace it with the cloned node. When you clone a node, every event listener associated with the element is entirely removed. This doesn't work well for removing just a single event listener. They're all removed.
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900