Is there a way to avoid global variable in this case?

I have a first function who has another function as parameter. And this function, creates a DOM element that must have onclick attribute with this parameter-function that comes from the first function! Just like this:

function funcOne(name,callback) {
    let button = document.createElement("button");
        button.setAttribute("id","myBtn");
        button.innerHTML = "Go to Func 2";
        button.setAttribute("onclick","funcTwo(this,'"+name+"','"+callback+"')");
    document.body.appendChild(button);
}

function funcTwo(element,name,callback) {
    let elementId = element.id;
    let yourName = name;
    console.log(yourName);
    callback();
}

funcOne('John',function(){alert('Holly cow!');});

The error, I believe, occurs in the “setAttribute” moment! And the only solution I’m seeing is to set:

globalThis.myGlobalCallback= callback;

Inside the funcOne. So I can call “myGlobalCallback()” from funcTwo and dismiss the use of setAttribute data during the element creation! (Because I can set only (“onclick”,”myGlobalCallback()”); But this isn’t the best way, it is?

Thanks for any help!

Answer

Assign the event listener using a JavaScript event listener instead of an HTML attribute, and you’ll be able to reference the name inside the funcOne closure instead of making it (or the callback) global.

function funcOne(name, callback) {
    const button = document.createElement("button");
    button.id = 'myBtn';
    button.textContent = "Go to Func 2";
    button.addEventListener('click',() => {
        funcTwo(button, name, callback);
    });
    document.body.appendChild(button);
}

function funcTwo(element, name, callback) {
    const elementId = element.id;
    const yourName = name;
    console.log(yourName);
    callback();
}

Best practice is to never, ever use inline handlers (that is, onclick="..." in the HTML) – use addEventListener instead, and many of your scope problems (and tedious quoting issues) will go away.