What you have isn't recursion. The doStuff
function just binds an event handler to an event, and you reuse the function in the event handler.
It's similar to recursion, but waiting for the event to happen breaks the chain. You need to think of handling event in a different way than procedural code, otherwise you will have difficulties when you have several different events to consider.
Reusing code is a great tool, but in this case it doesn't do very much. The way that you bind the events are not very similar, so you can just repeat the addEventListener
call in the two places, and the code gets even simpler:
function doMoreStuff() {
counter++;
var addStuff = document.getElementById("addStuff");
var stuff = document.createElement("input");
stuff.id = "change" + counter;
stuff.type = "text";
addStuff.appendChild(stuff);
stuff.addEventListener('change', doMoreStuff);
}
window.onload = function() {
document.getElementById("change0").addEventListener('change', doMoreStuff);
};