admin管理员组

文章数量:1402960

I have one input and one button. When I blur from the input and the input has changed, the price() function should be called. Also, when I click the button, the price() function should be called.

The problem is that when a user modifies the value of the input and clicks the button, the price() function is called twice. I don't want this to happen.

I tried the old-fashioned way, setting a variable "inPriceFunction" to true while entering and checking if it is not set before entering. This didn't worked because the two events (blur and click) are executed in the exact same time, the if and the variable set didn't had the time to occur.

How can I avoid that?

What I have tried:

<div>
    <input type=text onchange="price();" />
</div>
<button onclick="price();" />test</button>
<script>
called = 0;
function price() {
    if(called == true){
        return;
    } else {
        called = true;
    }
    console.log("called");
    called=false;
}
</script>

I have one input and one button. When I blur from the input and the input has changed, the price() function should be called. Also, when I click the button, the price() function should be called.

The problem is that when a user modifies the value of the input and clicks the button, the price() function is called twice. I don't want this to happen.

I tried the old-fashioned way, setting a variable "inPriceFunction" to true while entering and checking if it is not set before entering. This didn't worked because the two events (blur and click) are executed in the exact same time, the if and the variable set didn't had the time to occur.

How can I avoid that?

What I have tried:

<div>
    <input type=text onchange="price();" />
</div>
<button onclick="price();" />test</button>
<script>
called = 0;
function price() {
    if(called == true){
        return;
    } else {
        called = true;
    }
    console.log("called");
    called=false;
}
</script>
Share Improve this question edited May 17, 2013 at 13:18 Octavian asked May 17, 2013 at 12:52 OctavianOctavian 4,5899 gold badges29 silver badges40 bronze badges 4
  • 4 JavaScript is single-threaded so it can't be executed at the same time – EaterOfCode Commented May 17, 2013 at 12:56
  • Can you share some code showing how you are calling this function and what the function looks like? Because at @EaterOfCorpses said, you can't be calling the same function at the same time. – Matt Burland Commented May 17, 2013 at 12:58
  • The blur and click events will be emitted immediately after one another. What does the price() function do? Does it change a state, meaning something goes wrong if you call it twice, or do you just want to avoid something being rendered twice? If you only want it to be called first, then set a flag like "priceFunctionHasBeenCalled", in the other case use a buffering timeout. – Chris Commented May 17, 2013 at 13:02
  • In your example, it looks like called is always set to false before the method exits. – Brian J Commented Mar 14, 2014 at 14:42
Add a ment  | 

5 Answers 5

Reset to default 3

Underscore has you covered: http://underscorejs/#throttle

  • throttle will prevent your function being called twice within a specified length of time.
  • once will prevent your function being called twice at all.

The click and change event do not happen at the same time. They happen one after another.

  • First, the "change" event is fired, setting called = true, then execute console.log("called"); and set called=false again.
  • Then, the "click" event is fired, but called == false, so it sets called = true; and then execute console.log("called"); and set called=false again.

Here's a jsfiddle that will do the job. You shouldn't use global variables, of course:

http://jsfiddle/SZe26/

var clicktimer = null;

function clickfunc() {
    var BLOCK_TIME = 500;
    function handleclick() {
        console.log("Pressed!");
    }

    if (clicktimer) {
        console.log("Skipping handling of click!");
    } else {
        handleclick();
        clicktimer = setTimeout(function() {
            clicktimer = null;
        }, BLOCK_TIME);
    }
}

The sim^pliest way to handle that might be to store a datetime whenver Price is called and use it to check if it has been called too recently.

if (refDate > new Date(10000 + (new Date())) { // 1  second delay?
    return;
}

refDate = new Date();

It's likely that two calls to Date return the exact same date though (so no date manipulation would be required).

add a timeout, something like this

function schedludePrice() {

   if(myTimeOut){
      clearTimeout(myTimeOut);
   }
   myTimeOut = setTimeout('price()', 10);

}

this way if the function gets called twice in a short time by your blur and click event, the Price function will only be called once.

本文标签: