最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Two dom events that call the same function should call the function only once if happening in the same time - Stack

programmeradmin10浏览0评论

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.

与本文相关的文章

发布评论

评论列表(0)

  1. 暂无评论