Reputation: 37
I am grabbing the innerHTML off of a clicked list item in an unordered list. I save this string to a variable and I want to call a function with the same name as this variable.
I've done some research and found some different articles but none of it worked. eval was referenced as a haphazard way of doing it, but I could not get that to work. Also another was using Window but the code didn't work for me.
How can I call that variable as a function. i.e. clickedName()
right now calling clickedName() gives the error
Uncaught TypeError: clickedName is not a function
at HTMLUListElement.<anonymous>
Here is the code I am using:
index.html
<div id="myDiv">test</div>
<ul id="parent-list">
<li>Cats</li>
<li>Dogs</li>
</ul>
script.js
document.getElementById("parent-list").addEventListener("click", function(e) {
if (e.target && e.target.nodeName == "LI") {
// console.log(e.target.innerHTML + " was clicked");
// call function respective to element clicked
let clickedName = e.target.innerHTML;
console.log(clickedName);
}
});
function cat() {
const myElem = document.createElement("div");
let myString = `<div>Meow, Meow, Meow</div>`;
myElem.innerHTML = myString;
// put on page
document.getElementById("myDiv").append(myElem);
} // catClick
Upvotes: 1
Views: 275
Reputation: 5566
One way that I would not recommend is to know that functions declared "normally" (as in, with function fName() {}
in global scope) are part of the window object, so doFunction()
is the same as window.doFunction()
. Thus you can do this:
window[clickedName]();
But that means users can input the name of ANY function on the global scope to run it, which isn't great. Instead, I'd suggest encapsulating the functions you want to be able to run this way into a specific object holding just those methods; then you can call from that:
const allowedFunctions = {
firstAllowed: function() { /* ... */ },
someOtherFunction: function() { /* ... */ }
};
// ...then later, to call it...
if (allowedFunctions[clickedName]) { allowedFunctions[clickedName](); }
Upvotes: 2
Reputation: 665
If the function is declared in the current scope, this[clickedName]()
should work. This is because the function is a method on the this
object, and as such should be accessible through it. However, if the function is a part of another object, say anObject
, you can just do anObject[clickedName]()
Upvotes: 2