'Mousedown event not added

I'm adding an event listener but listener didn't added and i have no errors. I'm going to make a word game. And the problem is so weird

const alphabets = ["a","l","e","r","g"];
const xpos = [100,200,250,200,100];
const ypos = [500,500,550,600,600];
const words = ["large","age","ear"];
var divrows = [];
var divcells = [];
var isalphabetchoosed = [];
var divalphabets = [];
for(i in words){
    document.getElementById("body").innerHTML += `
    <div id='row` + i + `'></div><br>
    `;
    var thisrow = document.getElementById("row" + i);
    thisrow.style.display = "flex";
    thisrow.style.flexDirection = "row";
    thisrow.style.border = "2px solid black";
    thisrow.style.width = "400px";
    thisrow.style.height = "100px";
    thisrow.style.borderCollapse = "collapse";
    divrows.push(thisrow);
    divcells[i] = [];
    for(var j = 0;j < words[i].length;j++){
        thisrow.innerHTML += "<div id='cell" + i + j + "'></div>";
        divcells[i][j] = document.getElementById("cell" + i + j);
        divcells[i][j].style.flex = 1;
        divcells[i][j].style.border = "2px solid black";
        divcells[i][j].style.borderCollapse = "collapse";
    }
}
var lastwordchoosed = "";
for(i in alphabets){
    isalphabetchoosed[i] = false;
    document.getElementById("body").innerHTML += '<div id="alphabet' + i + '"></div>';
    var thisalphabet = document.getElementById("alphabet" + i);
    thisalphabet.style.position = "absolute";
    thisalphabet.style.left = xpos[i] + "px";
    thisalphabet.style.top = ypos[i] + "px";
    thisalphabet.innerHTML = alphabets[i];
    thisalphabet.style.width = "50px";
    thisalphabet.style.height = "50px";
    thisalphabet.style.backgroundColor = "khaki";
    thisalphabet.style.fontSize = "16pt";
    thisalphabet.style.textAlign = "center";
    thisalphabet.style.fontFamily = "Agency FB";
    divalphabets.push(thisalphabet);
    document.getElementById("alphabet" + i).onmousedown = updateword;
    debugger;
}
function updateword(event){
    lastwordchoosed += event.target.innerHTML;
    document.getElementById("wordchoosed").innerHTML = lastwordchoosed;
}
#wordchoosed{
    position: absolute;
    top: 450px;
    left: 120px;
    background-color: black;
    min-width: 50px;
    min-height: 20px;
    color: white;
    font-size: 18pt;
    font-family: Agency FB;
    text-align: center;
}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <link rel="stylesheet" href="index.css">
</head>
<body id="body">
    <span id="wordchoosed"></span>
</body>
<script src="index.js"></script>
</html>

thisalphabet : a div that when it clicks it adds the character to the field. lastwordchoosed : the word that must be write to the field. and i used debugger to see if it can see what is thisalphabet.Its defined
What should i do?



Solution 1:[1]

I fixed this problem by using setattribute :

    divalphabets[i].setAttribute("onmousedown",(event) => {
        lastwordchoosed += event.target.innerHTML;
        document.getElementById('wordchoosed').innerHTML = lastwordchoosed;
    });

Solution 2:[2]

If you use .innerHTML() to change an element's content, it loses it's event-listeners.

As you are using a for-loop to iterate through alphabets, with each iteration you lose the event-listeners bound in the iteration before. (That's why the only working button in your snippet is the "G", as it's bound last)

So do not bind the mousedown to any element inside the (later-on changed) body, but use document instead (See attached snippet), oh, and only do it once, as it's enough:

document.onmousedown = updateword;

const alphabets = ["a","l","e","r","g"];
const xpos = [100,200,250,200,100];
const ypos = [500,500,550,600,600];
const words = ["large","age","ear"];
var divrows = [];
var divcells = [];
var isalphabetchoosed = [];
var divalphabets = [];
for(i in words){
    document.getElementById("body").innerHTML += `
    <div id='row` + i + `'></div><br>
    `;
    var thisrow = document.getElementById("row" + i);
    thisrow.style.display = "flex";
    thisrow.style.flexDirection = "row";
    thisrow.style.border = "2px solid black";
    thisrow.style.width = "400px";
    thisrow.style.height = "100px";
    thisrow.style.borderCollapse = "collapse";
    divrows.push(thisrow);
    divcells[i] = [];
    for(var j = 0;j < words[i].length;j++){
        thisrow.innerHTML += "<div id='cell" + i + j + "'></div>";
        divcells[i][j] = document.getElementById("cell" + i + j);
        divcells[i][j].style.flex = 1;
        divcells[i][j].style.border = "2px solid black";
        divcells[i][j].style.borderCollapse = "collapse";
    }
}
var lastwordchoosed = "";
for(i in alphabets){
    isalphabetchoosed[i] = false;
    document.getElementById("body").innerHTML += '<div id="alphabet' + i + '"></div>';
    var thisalphabet = document.getElementById("alphabet" + i);
    thisalphabet.style.position = "absolute";
    thisalphabet.style.left = xpos[i] + "px";
    thisalphabet.style.top = ypos[i] + "px";
    thisalphabet.innerHTML = alphabets[i];
    thisalphabet.style.width = "50px";
    thisalphabet.style.height = "50px";
    thisalphabet.style.backgroundColor = "khaki";
    thisalphabet.style.fontSize = "16pt";
    thisalphabet.style.textAlign = "center";
    thisalphabet.style.fontFamily = "Agency FB";
    divalphabets.push(thisalphabet);
    debugger;
}
function updateword(event){
    lastwordchoosed += event.target.innerHTML;
    document.getElementById("wordchoosed").innerHTML = lastwordchoosed;
}

document.onmousedown = updateword;
#wordchoosed{
    position: absolute;
    top: 450px;
    left: 120px;
    background-color: black;
    min-width: 50px;
    min-height: 20px;
    color: white;
    font-size: 18pt;
    font-family: Agency FB;
    text-align: center;
}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <link rel="stylesheet" href="index.css">
</head>
<body id="body">
    <span id="wordchoosed"></span>
</body>
<script src="index.js"></script>
</html>

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 alireza
Solution 2