Skip to content
Advertisement

Can I use function generator as event handler?

I have a list of HTMLCollection:

<div class="demo">Access me by class[1]</div>
<div class="demo">Access me by class[2]</div>
<div class="demo">Access me by class[3]</div>
<div class="demo">Access me by class[4]</div>

And I have a script of JS:

var getElements = document.getElementsByClassName("demo");
const generatorObject = generatorFunction();

function* generatorFunction(e) { 
    for (i = 0; i < getElements.length; i++) { 
        yield getElements[i];
    }
}

generatorObject.next(); // each time pressed a key down will invoke this line 
// after invoking 6th time it will give {value: undefined, done: done}

My goal is to write a keyboardEvent based on .addEventListener("keydown", generatorFunction) method whereby event handler would be presented as function generator i.e. generatorFunction presented above. Is it good or bad practice?

Advertisement

Answer

Using a generator function directly as an event callback wouldn’t make any sense because calling the function wouldn’t execute its body, it would generate and return (to nowhere) an iterator.

Instead you’d need to wrap it in another function which talks to the iterator. I’m not sure exactly what your particular use case is (you talk about keydown events, but don’t say on what element). But here’s a general setup – in this example I’m yielding a number from an array on each keypress. On the final number, done is set to true.

function* generator() {
    let toYield = [1, 2, 3, 4];
    for (let i=0; i<toYield.length-1; i++) yield toYield[i];
    return toYield.pop(); //return final item in array, which sets iterator to done
}
const iterator = generator();
document.querySelector('input').addEventListener('keydown', evt => {
    let yielded = iterator.next();
    console.log(yielded);
});

Fiddle

2 People found this is helpful
Advertisement