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
5 Answers
Reset to default 3Underscore 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 executeconsole.log("called");
and setcalled=false
again. - Then, the "click" event is fired, but
called == false
, so it setscalled = true;
and then executeconsole.log("called");
and setcalled=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.