简体   繁体   中英

Understanding how functions use and store variables

My apologies is this has been asked/answered elsewhere. I may not know the correct terminology to find the desired results.

I'm building a sort of web app and in one area a user clicks a button, where a variable is obtained from the number at the end of the button's ID and is then passed to other functions for use in further processing. The issue I'm running into is that each subsequent time similar buttons are clicked, the variables from prior clicks are still stored within those functions.

JavaScript is not my forte, so I built a small fiddle that demonstrates my issue on a much smaller scale. If you click "Submit 1" in the fiddle, then click ALERT CUST_NUM, an alert box will display the variable's value. But if you repeat that process with either Submit 1 or Submit 2 (then clicking the ALERT button again), rather than alert a single instance of the variable, it will show multiple alert boxes in turn. And so on if you click Submit 1, then ALERT CUST_NUM, then Submit2, etc, such that it'll alert the chain of variables in a series of windows. I was hoping someone might explain why this occurs, as I would have expected only a single instance of the variable to exist within the function, being overwritten each time.

 $(".submit-btn1").click(function() { var cust_num = parseInt(this.id.replace('test-button-', ''), 10); testFunction(cust_num); }) $(".submit-btn2").click(function() { var cust_num = parseInt(this.id.replace('test-button-', ''), 10); testFunction(cust_num); }) function testFunction(cust_num) { $("#alert-btn").click(function() { alert(cust_num); }) }
 <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <button class="submit-btn1" id="test-button-1"> Submit 1 </button> <br/> <button class="submit-btn2" id="test-button-2"> Submit 2 </button> <br/> <button id="alert-btn"> ALERT CUST_NUM </button>

Every time you click on submit-btn1 or submit-btn2 , you are adding a new event handler with cust_num baked in to alert-btn . If you cleared the previous event handlers like in the following:

function testFunction(cust_num) {
    $("#alert-btn").off(); 
    $("#alert-btn").click(function(){ 
    alert(cust_num);
  })
}

Then you would have only one event handler.


A better approach would be to create a single event handler for alert-btn like so:

 var cust_num = 0; $(document).ready(function() { $(".mybuttons").click(function(){ cust_num = parseInt(this.id.replace('test-button-',''), 10); }) $("#alert-btn").click(function(){ alert(cust_num); }) });
 <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <button class="mybuttons" id="test-button-1">Submit 1</button> <br/> <button class="mybuttons" id="test-button-2">Submit 2</button> <br/> <button id="alert-btn">ALERT CUST_NUM</button>

I'd prefer a single handler for the input buttons that extracts the id and replaces the output button handler...

 $("#test-button-1, #test-button-2").click(function() { const alertWith = +(this.id.match(/\d+$/)[0]); // digits at end of a string $("#alert-btn").off('click').on('click', () => alert(alertWith)); });
 <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <button class="submit-btn1" id="test-button-1"> Submit 1 </button> <br/> <button class="submit-btn2" id="test-button-2"> Submit 2 </button> <br/> <button id="alert-btn"> ALERT CUST_NUM </button>

jdt's answer is spot on about what's happening with your code.

What is duplicated, as already explained, are the listeners attached to the click event, each with its instance of testFunction . Actually each time testFunction is called, there exists a single instance of test_num , as expected.

I don't like to skin cats;) and yet

There are more things in heaven and earth, Horatio, Than are dreamt of in your philosophy...

JQuery is a beautiful library, it offers many ways to approach this simple puzzle. One particular function that IMHO deserves attention is .data() link to official documentation

It allows to:

  • extract values from data attributes of an html tag
  • attach data to a dom element

In this situation, with minor changes to the html, these functionalities could be used to carry the number for each number button, and to attach it directly to the alert button.

 // listen for click event on any button with an id // that begins with 'test-button' $("button[id^='test-button']").click(function() { // take the value from the attribute of the clicked // element and assign it to the alert button $("#alert-btn").data("lastSelectedNum", $(this).data().num) }) $("#alert-btn").click( function() { // the alert will display the value assigned // or 'unset' if it's undefined alert( $(this).data().lastSelectedNum?? "unset") });
 <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <button id="test-button-1" data-num=1> Submit 1 </button> <br/> <button id="test-button-2" data-num=2> Submit 2 </button> <br/> <button id="alert-btn"> ALERT CUST_NUM </button>

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