On various pages of a website I generate via JavaScript different click handlers attached to links in the innerHTML
of an specific page element. I do it with a uitilty function like this:
function addClickLink(detail, detailHandler) {
element.innerHTML = `Info about <a href="#" onclick="${detailHandler.name}(); return false;">${detail}</a>`
}
Calling addClickLinkworks
works when detailHandler
is a defined function like
function heliumHandler () { ... }
addClickLinkworks("Helium", heliumHandler)
but not when I call addClickLinkworks
with an anonymous function:
addClickLinkworks("Helium", function() { ... })
How can I write the "onclick"
string for anonymous functions?
You could wrap the stringified version of the function, and then call it using (<stringified function source)()
so that the onclick
treats it as a function expression (rather than a statement):
const element = document.getElementById("element");
function addClickLink(detail, detailHandler) {
element.innerHTML = `Info about <a href="#" onclick="(${detailHandler})(); return false;">${detail}</a>`;
}
// This works:
//function heliumHandler() { console.log('function declaration'); }
//addClickLink("Helium", heliumHandler)
// And so does this:
addClickLink("Helium", function() { console.log('function expression'); })
<div id="element"></div>
However, I wouldn't suggest this, as it can fail for native functions for example, and won't work correctly for bound functions. Rather than doing that, I would recommend that you create a HTML element and add your listener to that using .addEventListener()
:
const element = document.getElementById("element");
function addClickLink(detail, detailHandler) {
const fragment = document.createDocumentFragment();
const textNode = document.createTextNode("Info about ");
const anchor = document.createElement('a');
anchor.href = "#";
anchor.innerText = detail;
anchor.addEventListener("click", e => {
e.preventDefault(); // similar to return false in your previous `onclick`
detailHandler();
});
fragment.appendChild(textNode);
fragment.appendChild(anchor);
element.replaceChildren(fragment);
}
// This works:
// function heliumHandler() { console.log('function declaration'); }
// addClickLink("Helium", heliumHandler)
// And so does this:
addClickLink("Helium", function() { console.log('function expression'); })
<div id="element"></div>