简体   繁体   中英

Why does my button increment the wrong variable?

very new to Javascript/jquery. I've been staring at this for a couple of days now and I can't figure it out. Out of practice I'm making a game where you distribute stats to your character. I can do the first stat, the values change and the console log shows it. However all the other buttons only increment the first stat. I know how boolean logic works, I've attempted to replicate it with what I've learned in Python and C++, but I seem to be missing something as the logic is broken or the code selects the wrong variable.

var PTS = 20;
var strength = 5;
var agility = 5;
var constitution = 5;

function points_append(){
    PTS = PTS - 1;
    console.log("Clicked $(#PTS_append), Total Points =", PTS);
    $("#total_points").text(PTS); 

    if ($("#PTS_append").hasClass("strength")) {
        strength = strength + 1;
        console.log("Added point to STRENGTH:", strength);
        $("#strength").text(strength);
    }

    else if ($("#PTS_append").hasClass(".agility")) {
        agility = agility + 1;
        console.log("Added point to AGILITY:", agility);
        $("#agility").text(agility);
    }
}

function points_remove(){
    PTS = PTS + 1;
    console.log("Clicked $(#PTS_remove), Total Points =", PTS);
    $("#total_points").text(PTS);

    if ($("#PTS_remove").parent("#parent_strength")) {
        strength = strength - 1;
        console.log("Removed point from STRENGTH:", strength);
        $("#strength").text(strength);
    }


    else if ($("#PTS_remove").parent("#parent_agility")) {
        agility = agility - 1;
        console.log("Removed point from AGILITY:", agility);
        $("#agility").text(agility);
    }
}

As you can see I've made attempts with both .parent and .hasClass among other things. Coincidentally this is my first post here, so here goes nothing. I also googled the issue back and forth but haven't arrived anywhere close to an answer. I hope someone here can help me.

EDIT: This is how the HTML looks.

<div class = "stats_allocation">

            <table>
            <tr>
                <th>Available PTS:</th>
                <td id = "total_points">20</td>
            </tr>
            <tr id = "parent_strength">
                <th>Strength:</th> 
                <td id="strength">5</td> 
                <td>
                    <button class = "strength" id = "PTS_append" onClick="points_append()">+</button>
                    <button class = "strength" id = "PTS_remove" onClick="points_remove()">-</button>
                </td>
            </tr>

            <tr id = "parent_agility">
                <th>Aglity:</th> 
                <td id="agility">5</td> 
                <td>
                    <button class = "agility" id = "PTS_append" onClick="points_append()">+</button>
                    <button class = "agility" id = "PTS_remove" onClick="points_remove()">-</button>
                </td>
            </tr>

            <tr id = "parent_constitution">
                <th>Constitution:</th> 
                <td id="constitution">5</td> 
                <td>
                    <button class = "constitution" id = "PTS_append" onClick="points_append()">+</button>
                    <button class = "constitution" id = "PTS_remove" onClick="points_remove()">-</button>
                </td>
            </tr>

            </table>

        </div>

Couple of issues:

  • id='' can only appear once in HTML. Using $("#id") will always find the first one, so you need to find the one relative to the button pressed
  • .hasClass is used without the class indicator
  • .parent() will only look at the node above (so for the button it will find the td ) - you could use .parents() or .closest() - or just use the .hasClass as before.

As you're using onclick=func you can pass the button using onclick=func(this) and then function fund(btn) .

If you were using jquery $("btn").on("click", function... then the button would be defined as this for you.

Updated code:

 var PTS = 20; var strength = 5; var agility = 5; var constitution = 5; function points_append(btn) { PTS = PTS - 1; console.log("Clicked $(#PTS_append), Total Points =", PTS); $("#total_points").text(PTS); if ($(btn).hasClass("strength")) { strength = strength + 1; console.log("Added point to STRENGTH:", strength); $("#strength").text(strength); } else if ($(btn).hasClass("agility")) { agility = agility + 1; console.log("Added point to AGILITY:", agility); $("#agility").text(agility); } } function points_remove(btn) { PTS = PTS + 1; console.log("Clicked $(#PTS_remove), Total Points =", PTS); $("#total_points").text(PTS); if ($(btn).closest("#parent_strength").length > 0) { strength = strength - 1; console.log("Removed point from STRENGTH:", strength); $("#strength").text(strength); } else if ($(btn).closest("#parent_agility").length > 0) { agility = agility - 1; console.log("Removed point from AGILITY:", agility); $("#agility").text(agility); } } 
 <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <div class="stats_allocation"> <table> <tr> <th>Available PTS:</th> <td id="total_points">20</td> </tr> <tr id="parent_strength"> <th>Strength:</th> <td id="strength">5</td> <td> <button class="strength" onClick="points_append(this)">+</button> <button class="strength" onClick="points_remove(this)">-</button> </td> </tr> <tr id="parent_agility"> <th>Aglity:</th> <td id="agility">5</td> <td> <button class="agility" onClick="points_append(this)">+</button> <button class="agility" onClick="points_remove(this)">-</button> </td> </tr> <tr id="parent_constitution"> <th>Constitution:</th> <td id="constitution">5</td> <td> <button style='display:none;' class="constitution" onClick="points_append(this)">+</button> <button style='display:none;' class="constitution" onClick="points_remove(this)">-</button> </td> </tr> </table> </div> 

To make this more 'jquery-y' (and to appease the purists), don't add event handlers in the html, updated snippet:

 $("button.add").on("click", points_append); $("button.remove").on("click", points_remove); var PTS = 20; var strength = 5; var agility = 5; var constitution = 5; function points_append() { PTS = PTS - 1; console.log("Clicked $(#PTS_append), Total Points =", PTS); $("#total_points").text(PTS); if ($(this).hasClass("strength")) { strength = strength + 1; console.log("Added point to STRENGTH:", strength); $("#strength").text(strength); } else if ($(this).hasClass("agility")) { agility = agility + 1; console.log("Added point to AGILITY:", agility); $("#agility").text(agility); } } function points_remove(btn) { PTS = PTS + 1; console.log("Clicked $(#PTS_remove), Total Points =", PTS); $("#total_points").text(PTS); if ($(this).closest("#parent_strength").length > 0) { strength = strength - 1; console.log("Removed point from STRENGTH:", strength); $("#strength").text(strength); } else if ($(this).closest("#parent_agility").length > 0) { agility = agility - 1; console.log("Removed point from AGILITY:", agility); $("#agility").text(agility); } } 
 <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <div class="stats_allocation"> <table> <tr> <th>Available PTS:</th> <td id="total_points">20</td> </tr> <tr id="parent_strength"> <th>Strength:</th> <td id="strength">5</td> <td> <button class="strength add">+</button> <button class="strength remove">-</button> </td> </tr> <tr id="parent_agility"> <th>Aglity:</th> <td id="agility">5</td> <td> <button class="agility add">+</button> <button class="agility remove">-</button> </td> </tr> </table> </div> 

There are other improvements that could be made such as using an object for your abilities and a single method to add/remove any attribute (by defining the attribute on the button container) which will greatly reduce your code and make it more reusable. But it's a good start.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM