0

I'm trying to write some Javascript so that when a button is clicked it creates a button with a onClick attribute.

Here is the HTML:

<button id = 'click'>Click</button>
<div id = 'newbutton'></div>

Here is the Javascript:

function click_function (id) {
    alert (id);
}
 document.addEventListener("DOMContentLoaded", () => {
     document.querySelector("#click").onclick = () => {
         alert ("Clicked");
         btn = document.createElement('button');
         btn.innerHTML = "Button"
         btn.id = 'button';
         btn.onclick = click_function(btn.id);
         document.querySelector('#newbutton').appendChild(btn);
     }
});

I'm trying to display an alert message with the button id when the 2nd button is clicked.

How can I make it so the click_function is only called when the second button is clicked?

eba340
  • 29
  • 4

2 Answers2

1

Don't assign the result of calling the function to onclick, assign an anonymous function which captures the thing you want to pass in (btn.id) instead:

btn.onclick = () => click_function(btn.id);
Rikki Gibson
  • 4,136
  • 23
  • 34
-1

From an outer function you can retrieve the element whos listener is bound to by using

Event.currentTarget

function click_function(evt) {
  console.log(evt.currentTarget.id);
}

document.addEventListener("DOMContentLoaded", () => {
  document.querySelector("#click").addEventListener("click", () => {
    console.log("Clicked");
    const btn = document.createElement('button');
    btn.textContent = "Button"
    btn.id = 'button';
    btn.addEventListener("click", click_function);
    document.querySelector('#newbutton').appendChild(btn);
  });
});
<button id='click'>Click</button>
<div id='newbutton'></div>

PS: when creating new element on-the-fly, the onclick is not such a bad practice - since it's its first bound event, but to assign events to already existent elements try always to use EventTarget.addEventListener - since oneelement can have multiple addEventListeners assigned, but only one on* handler.

If you're going to create many elements in your app, here's another way with reusable Element function helpers:

const EL = (sel, EL) => (EL || document).querySelector(sel);
const ELNew = (sel, attr) => Object.assign(document.createElement(sel), attr || {});

function click_function(id) {
  console.log(id);
}

EL("#click").addEventListener("click", () => {
  console.log("Clicked");
  const btn = ELNew('button', {
    id: "button",
    type: "button", // Otherwise by default type is "submit"
    textContent: "CLICK ME",
    onclick() {
      click_function(btn.id)
    }
  });
  EL('#newbutton').append(btn);
});
<button id='click'>Click</button>
<div id='newbutton'></div>

or, instead of calling a handler that again calls a function...

onclick() {
  click_function(btn.id)
}

or:

onclick: () => click_function(btn.id)

you could simply

onclick: click_function, 

and than use Event.currentTarget as in the first example - which provides you with more data than just getting the id.

Roko C. Buljan
  • 196,159
  • 39
  • 305
  • 313