Check if button has been clicked within time - javascript

This is what I'd like to do:
User clicks on button, Run Function A
If button hasn't been clicked again within 1 second, Run Function B too
If button has been clicked, repeat (run function A again and check for function B)
This is what I've tried
var clicked = false;
$('#button').click(function(){
A();
});
function A(){
clicked = true;
setTimeout(function(){
clicked == false;
)}, 1000);
setTimeout(function(){
if ( clicked == false ) {
B();
}
)}, 1000);
}
I think the code will for scenario 1 and 2, but how can I get it working for 3 too?
EDIT: Just saw a related SO question upon posting which I didn't find through search. Please wait while I check if it's a duplicate

I think you are looking to throttle (buffer) the clicks, that is, you want to wait a specified amount of time before you act, if the same event happens again within your throttling period, you restart your wait. http://jsfiddle.net/8QdLV/
function B() {
console.log('Clicked')
}
var timeoutId;
$('#button').click(function() {
clearTimeout(timeoutId);
timeOutId = setTimeout(B, 1000);
});
This can be generalized http://jsfiddle.net/8QdLV/
function throttle(handler, buffer) {
var timeoutId;
buffer = buffer || 1000;
return function(e) {
clearTimeout(timeoutId);
var me = this;
timeoutId = setTimeout(function() {
handler.call(me, e);
}, buffer);
}
}
$('button').click(throttle(function() {
console.log('Throttled click');
});
By the way, you may want to use https://code.google.com/p/jquery-debounce/ which also provides a $.throttle function

use the setInterval function.
note that it doesn't suffice to record the click with a boolean, otherwise two clicks at t=0, t=0.99 will both be cleared by the reset operation at t=1.
var clicked = false
, hnd_reset = null
, hnd_check = null;
$('#button').click(function() {
A();
});
function A(){
clicked = true;
hnd_reset = setTimeout(function(){
clicked = false;
hnd_reset = null;
)}, 1000);
if (hnd_check === null) {
hnd_check = setInterval(function(){
if ( !clicked && (hnd_reset === null)) {
clearInterval( hnd_check );
hnd_check = null;
B();
}
)}, 1000);
}
}
alternatively you could track the number of clicks in an int starting at 0, allowing for execution of B iff the tracker is 0.

Related

SetTiemout in SetInterval?

I have a strange problem, well I'm trying to make a loop using setInterval but i want to have a SetTimeout inside as well.
Seems, from the comments, what you need is just
var init = function() {
setTimeout(function(){
console.log("Hi");
init(); // only call init here to start again if need be
}, 8000);
}
init();
based on the comment below, I'm assuming the interval needs to be "paused" sometimes because in your comment you say at some point, I have to delay one action - which implies that this delay isn't always necessary. Given that, you could write it as follows
var test = function() {
var interval = setInterval(function() {
if (someCondition) {
clearInterval(interval); // stop the interval
setTimeout(function(){
console.log("Hi");
test(); // restart the interval
}, 8000);
} else {
// this is done every second, except when "someCondition" is true
}
}, 1000);
}
or even
var running = true;
var test = function() {
var interval = setInterval(function() {
if (someCondition) {
running = false; // stop the interval
setTimeout(function(){
console.log("Hi");
running = true; // restart the interval
}, 8000);
} else if (running) {
// this is done every second, only when "running" is true
}
}, 1000);
}

Incomprehensible work decorator function

Is a function:
var f = function(a) { console.log(a) };
function throttle(func, ms) {
var stop = false, savedThis, savedArgs;
return function wrapper() {
if(stop) {
savedArgs = arguments;
savedThis = this;
return;
}
func.apply(this, arguments)
stop = true;
setTimeout(function() {
stop = false;
if(savedArgs) {
wrapper.apply(savedThis, savedArgs);
savedArgs = savedThis = null;
}
}, ms);
};
}
// brake function to once every 1000 ms
var f1000 = throttle(f, 1000);
f1000(1); // print 1
f1000(2); // (brakes, less than 1000ms)
f1000(3); // (brakes, less than 1000ms)
The first call f1000 (1) displays 1. f1000 (2), the second call does not work, but it will keep in savedAggs link to the arguments of the second call. The third launch also does not work, but it will overwrite the link to the arguments of the third call. Through 1000 ms setTimeout cause an anonymous function, the variable will stop within the meaning of the false. Condition of work, and the wrapper will be called recursively. But then I can not understand what's going on? When this code works: savedArgs = savedThis = null;?
The function is a bit incomprehensible, yes. Its job is to throttle the rate of invocations to at most one per 1000 ms - however if they occur more frequent, it will also repeat the last invocation as soon as the timeout has finished.
It might better be written
function throttle(func, ms) {
var stop = false, savedThis, savedArgs;
function invoke() {
stop = true; // the last invocation will have been less than `ms` ago
func.apply(savedThis, savedArgs);
savedThis = savedArgs = null;
setTimeout(function() {
stop = false; // the timeout is over, start accepting new invocations
if (savedArgs) // there has been at least one invocation during
// the current timeout
invoke(); // let's repeat that
}, ms);
}
return function wrapper() {
savedArgs = arguments;
savedThis = this;
if (stop)
return;
else
invoke();
};
}

calling the same function multiple times while clicking

I have a function which accepts a string and outputs it one character at a time with a delay. The event occurs when the user clicks a link or button. The problem is that if the user clicks a link and then another before the first one is done, they both run at the same time and output to the screen. It becomes jumbled up.
ex:
string1 : "i like pie very much"
string1 : "so does the next guy"
output : i sloi kdeo epse .... and so on.
Anyone know a method to fix this?
I think I need a way to check if the function is being processed already, then wait till it is done before starting the next.
Place both functions inside an object (because globals are bad), add a variable to the object which knows if a function is executing, and check the variable, like this:
var ns = {
isExecuting:false,
func1: function(){
if (this.isExecuting) { return; }
this.isExecuting = true;
//do stuff 1
this.isExecuting = false;
},
func2: function(){
if (this.isExecuting) { return; }
this.isExecuting = true;
//do stuff 2
this.isExecuting = false;
}
}
and for extra elegance:
var ns = {
isExecuting:false,
executeConditionally:function(action){
if (this.isExecuting) { return; }
this.isExecuting = true;
action();
this.isExecuting = false;
}
func1: function(){
this.executeConditionally(function(){
//stuff
})
},
func2: function(){
this.executeConditionally(function(){
//stuff
})
}
}
add a variable globally or in scope outside the method called IsProcessing and set it to true the first time the method is called, on the method you can then just check if (IsProcessing) return false;
All you need to do is set a variable that indicates whether the function is running:
var isRunning = false;
$('a').click(function({
if(isRunning == false){
isRunning = true;
///Do stuff
isRunning = false;
}
else{
return false;
}
});
Don't you want all the clicks to be taken into account, but in order ?
If so, I suggest you separate streams between adding a click to process, and consuming clicks
:
the html :
<a class="example" href="javascript:void(0)" onclick="delayPushLine();">i like pie very much</a><br/>
<a class="example" href="javascript:void(0)" onclick="delayPushLine();">so does the next guy</a>
<div class="writeThere"></div>
and the javascript (using jQuery a bit)
var charDisplayDelay = 50; // the time between each char display
var displayDelay = 2000; // the time before a click is handled
var lines = [];
var lineIdx = 0, pos = 0;
function delayPushLine(e) {
if (!e) {
e = window.event
}
setTimeout(function() { lines.push(e.srcElement.innerText); }, displayDelay);
}
function showLines () {
if (lines.length > lineIdx) {
if (pos < lines[lineIdx].length) {
$(".writeThere").append(lines[lineIdx].substr(pos,1));
pos++;
} else {
pos = 0;
lineIdx++;
$(".writeThere").append("<br/>");
}
}
}
setInterval("showLines()", charDisplayDelay);
http://jsfiddle.net/kD4JL/1/

Is there a way to check if a var is using setInterval()?

For instance, I am setting an interval like
timer = setInterval(fncName, 1000);
and if i go and do
clearInterval(timer);
it does clear the interval but is there a way to check that it cleared the interval? I've tried getting the value of it while it has an interval and when it doesn't but they both just seem to be numbers.
There is no direct way to do what you are looking for. Instead, you could set timer to false every time you call clearInterval:
// Start timer
var timer = setInterval(fncName, 1000);
// End timer
clearInterval(timer);
timer = false;
Now, timer will either be false or have a value at a given time, so you can simply check with
if (timer)
...
If you want to encapsulate this in a class:
function Interval(fn, time) {
var timer = false;
this.start = function () {
if (!this.isRunning())
timer = setInterval(fn, time);
};
this.stop = function () {
clearInterval(timer);
timer = false;
};
this.isRunning = function () {
return timer !== false;
};
}
var i = new Interval(fncName, 1000);
i.start();
if (i.isRunning())
// ...
i.stop();
The return values from setTimeout and setInterval are completely opaque values. You can't derive any meaning from them; the only use for them is to pass back to clearTimeout and clearInterval.
There is no function to test whether a value corresponds to an active timeout/interval, sorry! If you wanted a timer whose status you could check, you'd have to create your own wrapper functions that remembered what the set/clear state was.
I did this like below, My problem was solved. you should set the value like "false", when you clearTimeout the timer.
var timeer=false;
----
----
if(timeer==false)
{
starttimer();
}
-----
-----
function starttimer()
{
timeer_main=setInterval(activefunction, 1000);
timeer=true;
}
function pausetimer()
{
clearTimeout(timeer_main);
timeer=false;
}
Well you can do
var interval = setInterval(function() {}, 1000);
interval = clearInterval(interval);
if (typeof interval === 'undefined'){
...
}
but what are you actually trying to do? clearInterval function is an always success function and it will always return undefined even if you call it with a NaN value, no error checking in there.
You COULD override the setInterval method and add the capability to keep track of your intervals. Here is an untestet example to outline the idea. It will work on the current window only (if you have multiple, you could change this with the help of the prototype object) and this will only work if you override the functions BEFORE any functions that you care of keeping track about are registered:
var oldSetInterval = window.setInterval;
var oldClearInterval = window.clearInterval;
window.setInterval = function(func, time)
{
var id = oldSetInterval(func, time);
window.intervals.push(id);
return id;
}
window.intervals = [];
window.clearInterval = function(id)
{
for(int i = 0; i < window.setInterval.intervals; ++i)
if (window.setInterval.intervals[i] == id)
{
window.setInterval.intervals.splice(i, 1);
}
oldClearInterval(id);
}
window.isIntervalRegistered(id)
{
for(int i = 0; i < window.setInterval.intervals; ++i)
if (window.setInterval.intervals[i] == func)
return true;
return false;
}
var i = 0;
var refreshLoop = setInterval(function(){
i++;
}, 250);
if (isIntervalRegistered(refrshLoop)) alert('still registered');
else alert('not registered');
clearInterval(refreshLoop);
if (isIntervalRegistered(refrshLoop)) alert('still registered');
else alert('not registered');
The solution to this problem: Create a global counter that is incremented within your code performed by setInterval. Then before you recall setInterval, test if the counter is STILL incrementing. If so, your setInterval is still active. If not, you're good to go.

How to delay the .keyup() handler until the user stops typing?

I’ve got a search field. Right now it searches for every keyup. So if someone types “Windows”, it will make a search with AJAX for every keyup: “W”, “Wi”, “Win”, “Wind”, “Windo”, “Window”, “Windows”.
I want to have a delay, so it only searches when the user stops typing for 200 ms.
There is no option for this in the keyup function, and I have tried setTimeout, but it didn’t work.
How can I do that?
I use this small function for the same purpose, executing a function after the user has stopped typing for a specified amount of time or in events that fire at a high rate, like resize:
function delay(callback, ms) {
var timer = 0;
return function() {
var context = this, args = arguments;
clearTimeout(timer);
timer = setTimeout(function () {
callback.apply(context, args);
}, ms || 0);
};
}
// Example usage:
$('#input').keyup(delay(function (e) {
console.log('Time elapsed!', this.value);
}, 500));
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<label for="input">Try it:
<input id="input" type="text" placeholder="Type something here..."/>
</label>
How it works:
The delay function will return a wrapped function that internally handles an individual timer, in each execution the timer is restarted with the time delay provided, if multiple executions occur before this time passes, the timer will just reset and start again.
When the timer finally ends, the callback function is executed, passing the original context and arguments (in this example, the jQuery's event object, and the DOM element as this).
UPDATE 2019-05-16
I have re-implemented the function using ES5 and ES6 features for modern environments:
function delay(fn, ms) {
let timer = 0
return function(...args) {
clearTimeout(timer)
timer = setTimeout(fn.bind(this, ...args), ms || 0)
}
}
The implementation is covered with a set of tests.
For something more sophisticated, give a look to the jQuery Typewatch plugin.
If you want to search after the type is done use a global variable to hold the timeout returned from your setTimout call and cancel it with a clearTimeout if it hasn't yet happend so that it won't fire the timeout except on the last keyup event
var globalTimeout = null;
$('#id').keyup(function(){
if(globalTimeout != null) clearTimeout(globalTimeout);
globalTimeout =setTimeout(SearchFunc,200);
}
function SearchFunc(){
globalTimeout = null;
//ajax code
}
Or with an anonymous function :
var globalTimeout = null;
$('#id').keyup(function() {
if (globalTimeout != null) {
clearTimeout(globalTimeout);
}
globalTimeout = setTimeout(function() {
globalTimeout = null;
//ajax code
}, 200);
}
Another slight enhancement on CMS's answer. To easily allow for separate delays, you can use the following:
function makeDelay(ms) {
var timer = 0;
return function(callback){
clearTimeout (timer);
timer = setTimeout(callback, ms);
};
};
If you want to reuse the same delay, just do
var delay = makeDelay(250);
$(selector1).on('keyup', function() {delay(someCallback);});
$(selector2).on('keyup', function() {delay(someCallback);});
If you want separate delays, you can do
$(selector1).on('keyup', function() {makeDelay(250)(someCallback);});
$(selector2).on('keyup', function() {makeDelay(250)(someCallback);});
You could also look at underscore.js, which provides utility methods like debounce:
var lazyLayout = _.debounce(calculateLayout, 300);
$(window).resize(lazyLayout);
Explanation
Use a variable to store the timeout function. Then use clearTimeout() to clear this variable of any active timeout functions, and then use setTimeout() to set the active timeout function again. We run clearTimeout() first, because if a user is typing "hello", we want our function to run shortly after the user presses the "o" key (and not once for each letter).
Working Demo
Super simple approach, designed to run a function after a user has finished typing in a text field...
$(document).ready(function(e) {
var timeout;
var delay = 2000; // 2 seconds
$('.text-input').keyup(function(e) {
$('#status').html("User started typing!");
if(timeout) {
clearTimeout(timeout);
}
timeout = setTimeout(function() {
myFunction();
}, delay);
});
function myFunction() {
$('#status').html("Executing function for user!");
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
Status: <span id="status">Default Status</span><br>
<textarea name="text-input" class="text-input"></textarea>
Based on the answer of CMS, I made this :
Put the code below after include jQuery :
/*
* delayKeyup
* http://code.azerti.net/javascript/jquery/delaykeyup.htm
* Inspired by CMS in this post : http://stackoverflow.com/questions/1909441/jquery-keyup-delay
* Written by Gaten
* Exemple : $("#input").delayKeyup(function(){ alert("5 secondes passed from the last event keyup."); }, 5000);
*/
(function ($) {
$.fn.delayKeyup = function(callback, ms){
var timer = 0;
$(this).keyup(function(){
clearTimeout (timer);
timer = setTimeout(callback, ms);
});
return $(this);
};
})(jQuery);
And simply use like this :
$('#input').delayKeyup(function(){ alert("5 secondes passed from the last event keyup."); }, 5000);
Careful : the $(this) variable in the function passed as a parameter does not match input
jQuery:
var timeout = null;
$('#input').keyup(function() {
clearTimeout(timeout);
timeout = setTimeout(() => {
console.log($(this).val());
}, 1000);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>
<input type="text" id="input" placeholder="Type here..."/>
Pure Javascript:
let input = document.getElementById('input');
let timeout = null;
input.addEventListener('keyup', function (e) {
clearTimeout(timeout);
timeout = setTimeout(function () {
console.log('Value:', input.value);
}, 1000);
});
<input type="text" id="input" placeholder="Type here..."/>
Delay Multi Function Calls using Labels
This is the solution i work with. It will delay the execution on ANY function you want. It can be the keydown search query, maybe the quick click on previous or next buttons ( that would otherwise send multiple request if quickly clicked continuously , and be not used after all). This uses a global object that stores each execution time, and compares it with the most current request.
So the result is that only that last click / action will actually be called, because those requests are stored in a queue, that after the X milliseconds is called if no other request with the same label exists in the queue!
function delay_method(label,callback,time){
if(typeof window.delayed_methods=="undefined"){window.delayed_methods={};}
delayed_methods[label]=Date.now();
var t=delayed_methods[label];
setTimeout(function(){ if(delayed_methods[label]!=t){return;}else{ delayed_methods[label]=""; callback();}}, time||500);
}
You can set your own delay time ( its optional, defaults to 500ms). And send your function arguments in a "closure fashion".
For example if you want to call the bellow function:
function send_ajax(id){console.log(id);}
To prevent multiple send_ajax requests, you delay them using:
delay_method( "check date", function(){ send_ajax(2); } ,600);
Every request that uses the label "check date" will only be triggered if no other request is made in the 600 miliseconds timeframe. This argument is optional
Label independency (calling the same target function) but run both:
delay_method("check date parallel", function(){send_ajax(2);});
delay_method("check date", function(){send_ajax(2);});
Results in calling the same function but delay them independently because of their labels being different
If someone like to delay the same function, and without external variable he can use the next script:
function MyFunction() {
//Delaying the function execute
if (this.timer) {
window.clearTimeout(this.timer);
}
this.timer = window.setTimeout(function() {
//Execute the function code here...
}, 500);
}
This function extends the function from Gaten's answer a bit in order to get the element back:
$.fn.delayKeyup = function(callback, ms){
var timer = 0;
var el = $(this);
$(this).keyup(function(){
clearTimeout (timer);
timer = setTimeout(function(){
callback(el)
}, ms);
});
return $(this);
};
$('#input').delayKeyup(function(el){
//alert(el.val());
// Here I need the input element (value for ajax call) for further process
},1000);
http://jsfiddle.net/Us9bu/2/
I'm surprised that nobody mention the problem with multiple input in CMS's very nice snipped.
Basically, you would have to define delay variable individually for each input. Otherwise if sb put text to first input and quickly jump to other input and start typing, callback for the first one WON'T be called!
See the code below I came with based on other answers:
(function($) {
/**
* KeyUp with delay event setup
*
* #link http://stackoverflow.com/questions/1909441/jquery-keyup-delay#answer-12581187
* #param function callback
* #param int ms
*/
$.fn.delayKeyup = function(callback, ms){
$(this).keyup(function( event ){
var srcEl = event.currentTarget;
if( srcEl.delayTimer )
clearTimeout (srcEl.delayTimer );
srcEl.delayTimer = setTimeout(function(){ callback( $(srcEl) ); }, ms);
});
return $(this);
};
})(jQuery);
This solution keeps setTimeout reference within input's delayTimer variable. It also passes reference of element to callback as fazzyx suggested.
Tested in IE6, 8(comp - 7), 8 and Opera 12.11.
This worked for me where I delay the search logic operation and make a check if the value is same as entered in text field. If value is same then I go ahead and perform the operation for the data related to search value.
$('#searchText').on('keyup',function () {
var searchValue = $(this).val();
setTimeout(function(){
if(searchValue == $('#searchText').val() && searchValue != null && searchValue != "") {
// logic to fetch data based on searchValue
}
else if(searchValue == ''){
// logic to load all the data
}
},300);
});
Delay function to call up on every keyup.
jQuery 1.7.1 or up required
jQuery.fn.keyupDelay = function( cb, delay ){
if(delay == null){
delay = 400;
}
var timer = 0;
return $(this).on('keyup',function(){
clearTimeout(timer);
timer = setTimeout( cb , delay );
});
}
Usage: $('#searchBox').keyupDelay( cb );
From ES6, one can use arrow function syntax as well.
In this example, the code delays keyup event for 400ms after users finish typeing before calling searchFunc make a query request.
const searchbar = document.getElementById('searchBar');
const searchFunc = // any function
// wait ms (milliseconds) after user stops typing to execute func
const delayKeyUp = (() => {
let timer = null;
const delay = (func, ms) => {
timer ? clearTimeout(timer): null
timer = setTimeout(func, ms)
}
return delay
})();
searchbar.addEventListener('keyup', (e) => {
const query = e.target.value;
delayKeyUp(() => {searchFunc(query)}, 400);
})
Updated Typescript version:
const delayKeyUp = (() => {
let timer: NodeJS.Timeout;
return (func: Function, ms: number) => {
timer ? clearTimeout(timer) : null;
timer = setTimeout(() => func(), ms);
};
})();
This is a solution along the lines of CMS's, but solves a few key issues for me:
Supports multiple inputs, delays can run concurrently.
Ignores key events that didn't changed the value (like Ctrl, Alt+Tab).
Solves a race condition (when the callback is executed and the value already changed).
var delay = (function() {
var timer = {}
, values = {}
return function(el) {
var id = el.form.id + '.' + el.name
return {
enqueue: function(ms, cb) {
if (values[id] == el.value) return
if (!el.value) return
var original = values[id] = el.value
clearTimeout(timer[id])
timer[id] = setTimeout(function() {
if (original != el.value) return // solves race condition
cb.apply(el)
}, ms)
}
}
}
}())
Usage:
signup.key.addEventListener('keyup', function() {
delay(this).enqueue(300, function() {
console.log(this.value)
})
})
The code is written in a style I enjoy, you may need to add a bunch of semicolons.
Things to keep in mind:
A unique id is generated based on the form id and input name, so they must be defined and unique, or you could adjust it to your situation.
delay returns an object that's easy to extend for your own needs.
The original element used for delay is bound to the callback, so this works as expected (like in the example).
Empty value is ignored in the second validation.
Watch out for enqueue, it expects milliseconds first, I prefer that, but you may want to switch the parameters to match setTimeout.
The solution I use adds another level of complexity, allowing you to cancel execution, for example, but this is a good base to build on.
Combining CMS answer with Miguel's one yields a robust solution allowing concurrent delays.
var delay = (function(){
var timers = {};
return function (callback, ms, label) {
label = label || 'defaultTimer';
clearTimeout(timers[label] || 0);
timers[label] = setTimeout(callback, ms);
};
})();
When you need to delay different actions independently, use the third argument.
$('input.group1').keyup(function() {
delay(function(){
alert('Time elapsed!');
}, 1000, 'firstAction');
});
$('input.group2').keyup(function() {
delay(function(){
alert('Time elapsed!');
}, 1000, '2ndAction');
});
Building upon CMS's answer here's new delay method which preserves 'this' in its usage:
var delay = (function(){
var timer = 0;
return function(callback, ms, that){
clearTimeout (timer);
timer = setTimeout(callback.bind(that), ms);
};
})();
Usage:
$('input').keyup(function() {
delay(function(){
alert('Time elapsed!');
}, 1000, this);
});
If you want to do something after a period of time and reset that timer after a specific event like keyup, the best solution is made with clearTimeout and setTimeout methods:
// declare the timeout variable out of the event listener or in the global scope
var timeout = null;
$(".some-class-or-selector-to-bind-event").keyup(function() {
clearTimeout(timout); // this will clear the recursive unneccessary calls
timeout = setTimeout(() => {
// do something: send an ajax or call a function here
}, 2000);
// wait two seconds
});
Use
mytimeout = setTimeout( expression, timeout );
where expression is the script to run and timeout is the time to wait in milliseconds before it runs - this does NOT hault the script, but simply delays execution of that part until the timeout is done.
clearTimeout(mytimeout);
will reset/clear the timeout so it does not run the script in expression (like a cancel) as long as it has not yet been executed.
Based on the answer of CMS, it just ignores the key events that doesn't change value.
var delay = (function(){
var timer = 0;
return function(callback, ms){
clearTimeout (timer);
timer = setTimeout(callback, ms);
};
})();
var duplicateFilter=(function(){
var lastContent;
return function(content,callback){
content=$.trim(content);
if(content!=lastContent){
callback(content);
}
lastContent=content;
};
})();
$("#some-input").on("keyup",function(ev){
var self=this;
delay(function(){
duplicateFilter($(self).val(),function(c){
//do sth...
console.log(c);
});
}, 1000 );
})
User lodash javascript library and use _.debounce function
changeName: _.debounce(function (val) {
console.log(val)
}, 1000)
Use the bindWithDelay jQuery plugin:
element.bindWithDelay(eventType, [ eventData ], handler(eventObject), timeout, throttle)
var globalTimeout = null;
$('#search').keyup(function(){
if(globalTimeout != null) clearTimeout(globalTimeout);
globalTimeout =setTimeout(SearchFunc,200);
});
function SearchFunc(){
globalTimeout = null;
console.log('Search: '+$('#search').val());
//ajax code
};
Here is a suggestion I have written that takes care of multiple input in your form.
This function gets the Object of the input field, put in your code
function fieldKeyup(obj){
// what you want this to do
} // fieldKeyup
This is the actual delayCall function, takes care of multiple input fields
function delayCall(obj,ms,fn){
return $(obj).each(function(){
if ( typeof this.timer == 'undefined' ) {
// Define an array to keep track of all fields needed delays
// This is in order to make this a multiple delay handling
function
this.timer = new Array();
}
var obj = this;
if (this.timer[obj.id]){
clearTimeout(this.timer[obj.id]);
delete(this.timer[obj.id]);
}
this.timer[obj.id] = setTimeout(function(){
fn(obj);}, ms);
});
}; // delayCall
Usage:
$("#username").on("keyup",function(){
delayCall($(this),500,fieldKeyup);
});
Take a look at the autocomplete plugin. I know that it allows you to specify a delay or a minimum number of characters. Even if you don't end up using the plugin, looking through the code will give you some ideas on how to implement it yourself.
Well, i also made a piece of code for limit high frequency ajax request cause by Keyup / Keydown. Check this out:
https://github.com/raincious/jQueue
Do your query like this:
var q = new jQueue(function(type, name, callback) {
return $.post("/api/account/user_existed/", {Method: type, Value: name}).done(callback);
}, 'Flush', 1500); // Make sure use Flush mode.
And bind event like this:
$('#field-username').keyup(function() {
q.run('Username', this.val(), function() { /* calling back */ });
});
Saw this today a little late but just want to put this here in case someone else needed. just separate the function to make it reusable. the code below will wait 1/2 second after typing stop.
var timeOutVar
$(selector).on('keyup', function() {
clearTimeout(timeOutVar);
timeOutVar= setTimeout(function(){ console.log("Hello"); }, 500);
});
// Get an global variable isApiCallingInProgress
// check isApiCallingInProgress
if (!isApiCallingInProgress) {
// set it to isApiCallingInProgress true
isApiCallingInProgress = true;
// set timeout
setTimeout(() => {
// Api call will go here
// then set variable again as false
isApiCallingInProgress = false;
}, 1000);
}

Categories