Shawn Shawn - 3 months ago 10
Javascript Question

JS: I have a function that activates twice instead of once?

I have a video game where a player can select up to 3 skills when he chooses to upgrade them. So imagine its time for you to upgrade 1 of your skills, a radial selector pops up, giving you the option to choose 3 different skills.

enter image description here

The function I have below works if the user clicks 1 time on any skill. However during the testing phase, I clicked the "upgrade me" button to activate it, then I selected "strike" and then "defend" (or multiple skills). Then I clicked the first skill on the radial selector. Instead of that 1 skill getting upgraded, it upgraded BOTH skills.

Strike gets replaced with Deepcut

Defend gets replaced with StoneWall

Only ONE skill should of been upgraded, NOT both.

When I reviewed my function below, I cannot figure out why both buttons update at the same time after multiple clicks. I am assuming it was adding the list together, but when I did console.log(list), it only referenced the skills I coded in the switch statement.

function radialSelector(object){
var list;
switch (object){
case strike:
list = [deepcut, balancedstrike, fury];
break;
case defend:
list = [stonewall, digin, holdtheline];
break;
default:
console.log("radialSelector() has set its switch statement to default")
}

console.log(object);
console.log(list);
for (var i=0, l=list.length; i<l; i++) {
radialSubMenuSkills("position"+(i+1), list[i]);
}


$('#upgradeSkillsBar').on('click', '#position1', function(){
removeSkillButton(object);
addSkillButton(list[0]);
removeRadialSubMenu();
});
}


Extra Code

function removeSkillButton(object) {
var x = dom.el(object.name);
x.parentNode.removeChild(x);
}

function addSkillButton(object) {
var button = document.createElement("button");
var target = dom.el("skillListWrapper");
button.textContent = object.name;
button.setAttribute("id", object.name);
button.setAttribute("class", "selection");

switch(object.category){
case "Attack":
target.insertBefore(button, target.children[0]);
break;
case "Defend":
target.insertBefore(button, target.children[1]);
break;
case "Healing":
target.insertBefore(button, target.children[2]);
break;
case "Debuff":
target.insertBefore(button, target.children[3]);
break;
default:
console.log("addSkillButton() - Case Statement has switched to default");
}
}

Answer

The reason both skills get upgraded, is that whenever you click to select a skill, you attach a click handler to #upgradeSkillsBar. These accumulate, i.e. the assignment of the handler does not replace the previously assigned handler, but adds a new one to the list of handlers to execute on the click event.

To avoid this accumulation, call .off() before .on(), like this:

$('#upgradeSkillsBar').off('click').on('click', '#position1', function(){
    //... etc