My real name
My real name

Reputation: 547

Onclick not working on dynamic rendering html

I wanna create a method to rendering a new button inside a div, and then add some click event on it. Here is my code:

let create = () => {
    function abc() {
        alert("abc")
    }

    let t = document.querySelectorAll(".here")[0];
    t.innerHTML = "<button onclick='abc()'>click me 2</button>";
}

document.querySelector("#clickme").addEventListener("click", () => {
    create()
})
<button id="clickme">
    click me
</button>

<div class="here">
    a
</div>

Click the "click me 2", why my abc() is not defined?

Upvotes: 0

Views: 512

Answers (2)

pouria
pouria

Reputation: 1008

The function call inside onclick attribute (and other attribute even handlers) are run in global scope so it has no access to this abc function.

So onclick='abc()' is equivalent to onclick='window.abc()'

You have two ways in order to make it work:

1- window.abc = abc:

let create = () => {
    function abc() {
        alert("abc")
    }

    window.abc = abc;

    let t = document.querySelectorAll(".here")[0];
    t.innerHTML = "<button onclick='abc()'>click me 2</button>";
}

Which is not really recommended.

2- Use addEventListener which is the best option here:

let create = () => {
    function abc() {
        alert("abc")
    }

    let t = document.querySelectorAll(".here")[0];
    t.innerHTML = "<button id='clickme2'>click me 2</button>";

    const clickme2 = document.querySelector('#clickme2');
    clickme2.addEventListener('click', abc);
}

Upvotes: 2

Jamiec
Jamiec

Reputation: 136154

Click the "click me 2", why my abc() is not defined?

Because attribute event handlers look for the method in global scope, and your abc method is not in global scope, it is in the scope of create

Upvotes: 3

Related Questions