1

I'm trying to make a reusable function that can take in a dynamic "action" for reusability...

In this case, adding the background color is the action.

const button = document.querySelector("#button");
const items = document.querySelectorAll(`*[id^="eventHandlerCreatedItem"]`); 

var eventHandler = (refEl, event, focusEls, action) => {
    refEl.addEventListener(`${event}`, () => {
        focusEls.forEach((focusEl) => {
            // focusEl.style.backgroundColor = "orange"; // works
            focusEl.`${action}`; // doesn't work
        });
    });
};

eventHandler(button, "click", items, 'style.backgroundColor = "orange"');

Thanks!

Michael Martell
  • 141
  • 2
  • 16
  • You can't access properties with [dot notation](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Property_accessors#dot_notation) using dynamic values, you need to use [bracket notation](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Property_accessors#bracket_notation). You also don't need all the template literals. `focusEl[action]` and `refEl.addEventListener(event, () =>`. But you also can't pass compound property paths (`'style.backgroundColor'`). Better all around to pass a callback. – pilchard Nov 30 '22 at 19:06
  • Does this answer your question? [Accessing an object property with a dynamically-computed name](https://stackoverflow.com/questions/4244896/accessing-an-object-property-with-a-dynamically-computed-name) – pilchard Nov 30 '22 at 19:09
  • 3
    This is going to involve much more than just accessing a property. The easiest path would probably be to pass in a function as the "action" rather than a string. Otherwise you're probably looking at either making some horrible use of `eval` or in some way tokenizing your string and processing it as a kind of mini-language. – David Nov 30 '22 at 19:14
  • I changed to focusEl[action], and tried both 'style.backgroundColor = "orange"' and '.style.backgroundColor = "orange"' and I'm not getting either of them to work. Im in a playground rn so there's no other code to make more complex... – Michael Martell Nov 30 '22 at 19:15

1 Answers1

3

Don't use a string for this. An "action" semantically describes a "function", use a function:

var eventHandler = (refEl, event, focusEls, action) => {
    refEl.addEventListener(`${event}`, () => {
        focusEls.forEach((focusEl) => {
            action(focusEl);
        });
    });
};

eventHandler(button, "click", items, (el) => el.style.backgroundColor = "orange");
David
  • 208,112
  • 36
  • 198
  • 279