Fallen Apart Fallen Apart - 7 months ago 24
Javascript Question

Recursive functions and removeEventListener

I want to write a dynamic button creator. So I have the

html
file

<body>
<button id="0" type="button" onclick="create_button(0)">Create button 1</button>
</body>


and
js
file which "simulates" proper action

var counter = 0;

function create_button(n) {

/*Shift up*/
for (i=counter; i>n; i--) {
document.getElementById(i).id = i+1;
document.getElementById(i+1).innerHTML = i+1;
};

/*Create new button*/
var new_button = document.createElement("Button");
new_button.innerHTML = n+1;
new_button.type = "button";
new_button.id = n+1;
function helper() {
create_button(n+1);
};
new_button.addEventListener('click', helper );

document.body.insertBefore(new_button,document.getElementById(n).nextSibling);

counter++;
};


However
/*Shift up*/
part only changes
id
and
innerHTML
of buttons not the action of
click
. So in order to fix that I need to add in
/*Shift up*/
two lines which should work as

document.getElementById(i+1).addEventListener('click', helper(i+1) );
document.getElementById(i+1).removeEventListener('click', helper(i) );


Clearly It will not work. Due to recursive nature of
create_button
function, I imagine that
helper
should be moved outside of
create_button
. But I have no idea how to do it.

Some additional info I simplified the code, but in practice buttons have some addition functions which depend on n. Let say that we also want to alert the position of the button. So we change helper to

function helper() {
create_button(n+1);
alert(n+1);
};


See in https://jsfiddle.net/o3Lsttyq/3/ what alerts say. Click for example 1,1,3.

Answer

Since your adjusting id so that it always matches the current index and your function helper wants that same index, it seems all you need to do is move your helper function out and change it to something like:

function helper(){
  var n1 = this.id; // effectively "n+1"
  alert(n1);
}

You don't need to call create_button with that argument either since the data you want can be pulled out of this.

(Also, you shouldn't be using the id attribute for that kind of thing. You should instead be using data- prefixed attributes as described here. As well, refactoring around using this instead of using getElementById() means you could drop the need for tracking the element's index.)