Home > Enterprise >  Is there a way to use the html written by js in addEventListener?
Is there a way to use the html written by js in addEventListener?

Time:11-18

I added 5 buttons in js to html and I want them to be defined with a one second delay, and because of this js, when it reaches the addEventListener line, those buttons are not defined and gives an error.

enter image description here

HTML:

<!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">
    <link rel="stylesheet" href="./style.css">
    <title>Document</title>
</head>
<body>
    <div id="btn-adder"></div>
    <script src="./script.js"></script>
</body>
</html>

CSS:

*{
    padding: 0;
    margin: 0;
    box-sizing: border-box;
    font-size: 20px;
}
body{
    background: rgb(61, 61, 61);
}
#btn-adder{
    margin-top: 40px;
    text-align: center;
}
#btn-adder button{
    padding: 5px;
    margin: 5px;
}

JavaScript:

const btnAdder = document.getElementById("btn-adder");
for (let i = 0; i < 5; i  ) {
    setTimeout(function () {
        btnAdder.innerHTML  = `<button id="btn${i}">Button ${i}</button>`;
    }, 1000);
}
for (let i = 0; i < 5; i  ) {
    document.getElementById(`btn${i}`).addEventListener("click", function () {
        console.log(`Button ${i} clicked`);
    });
}

Is there a way to make the addEventListener recognize the new variables?

CodePudding user response:

Yes it's possible and you don't even need the second loop, which is slowing down your code. (even though you probably won't notice it)

Instead of adding the HTML directly to the btn-adder, you can create a new button and directly attach the eventlistener to it.

You can create a new HTML element with document.createElement() and then add all attributes, eventlisteners and everything else you need to the button.
Finally you'll add the newly created button with appendChild() as a new child element to your btn-adder element.

const btnAdder = document.getElementById("btn-adder");
for (let i = 0; i < 5; i  ) {
    setTimeout(function () {
        // create button
        const buttonElement = document.createElement('button');
        buttonElement.id = `btn${i}`;
        buttonElement.textContent = `Button ${i}`
        
        // add eventlistener to the created button
        buttonElement.addEventListener("click", function () {
            console.log(`Button ${i} clicked`);
        });
        
        // add button to their parent
        btnAdder.appendChild(buttonElement);
    }, 1000);
}
*{
    padding: 0;
    margin: 0;
    box-sizing: border-box;
    font-size: 20px;
}
body{
    background: rgb(61, 61, 61);
}
#btn-adder{
    margin-top: 40px;
    text-align: center;
}
#btn-adder button{
    padding: 5px;
    margin: 5px;
}
<!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">
    <link rel="stylesheet" href="./style.css">
    <title>Document</title>
</head>
<body>
    <div id="btn-adder"></div>
    <script src="./script.js"></script>
</body>
</html>

CodePudding user response:

An approach close to what billyonecan mentioned but with use of appendChild instead of innerHTML which can lead to unwanted behaviour.

<!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">
    <link rel="stylesheet" href="./style.css">
    <style>
        *{
            padding: 0;
            margin: 0;
            box-sizing: border-box;
            font-size: 20px;
        }
        body{
            background: rgb(61, 61, 61);
        }
        #btn-adder{
            margin-top: 40px;
            text-align: center;
        }
        #btn-adder button{
            padding: 5px;
            margin: 5px;
        }
    </style>

    <title>Document</title>
</head>
<body>
    <div id="btn-adder"></div>
        <script>
        const btnAdder = document.getElementById("btn-adder");
        for (let i = 0; i < 5; i  ) {
            setTimeout(function () {
                let b = document.createElement('button');
                b.id = "btn"   i;
                b.textContent = "Button "   i;
                btnAdder.appendChild(b);
                
                document.getElementById("btn" i).addEventListener("click", function () {
                console.log(`Button ${i} clicked`);
            });
         },1000 );

        }
    </script>
</body>
</html>
  • Related