Reputation: 547
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
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
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