JS Function self-disable for a specific time after execution - javascript

I'm trying to create a function which is executed by a keypress and disabled for a specific time after execution.
function do_something() {
console.log('lorem ipsum');
}
document.onkeypress = function(e) {
if (e.keyCode == '32') {
do_something();
}
}
Is there any way to disable it for (let's say) 2 seconds after every execution?

Yes, there is a way: use a Timeout to temporally set a boolean to certain value and then check it's value before calling do_something().
Example:
let cooldown = false;
const RECHARGE_TIME = 2000; //ms
function do_something() {
console.log('lorem ipsum');
}
document.onkeypress = function(e) {
if (!cooldown && e.keyCode == '32') {
do_something();
startCooldown();
}
}
function startCooldown() {
cooldown = true;
setTimeout (function(){ cooldown = false}, RECHARGE_TIME);
}
EDIT: as Mosè Raguzzini noted: Depending on how important accuracy is, maybe this isn't the best method, since (as you can see here) it can be inacurate.

Try that, is a very simple and straightforward solution:
var firstExecution = 0; // Store the first execution time
var interval = 2000; // 2 seconds
function do_something() {
// current date
var date = new Date();
var milliseconds = date.getTime();
if((milliseconds - firstExecution) > interval){
firstExecution = milliseconds;
console.log('lorem ipsum');
} else {
console.log('too early');
}
}
document.onkeypress = function(e) {
if (e.keyCode == '32') {
do_something();
}
}

A very silly answer would be to sleep javascript execution for a specific time.
function sleep(delay) {
var start = new Date().getTime();
while (new Date().getTime() < start + delay);
}
Then
document.onkeypress = function(e) {
if (e.keyCode == '32') {
do_something();
sleep(2000);
}
}
I said silly because it stop your entire script for a specific time, you may not need that behavior!

Some thing like that, execution will be disable for 5s
var lastClicked = 0;
document.onkeypress = function(e) {
var now = new Date();
if (now - lastClicked > 5000) { //set a 5s delay
lastClicked = now;
if (e.keyCode == '32') {
do_something();
}
}
}
function do_something() {
console.log('lorem ipsum');
}

var timeout = false; //Control variable
var miliseconds = 2000; //Time in miliseconds for the function to enable again
function do_something() {
if(timeout) return alert("Function disabled");
console.log('lorem ipsum');
timeout = true;
setTimeout(function() { timeout = false }, miliseconds);
}
document.onkeypress = function(e) {
if (e.keyCode == '32') {
do_something();
}
}

Lodash has throttle for this purpose.

Related

how to stop function from executing again until a certain time has passed

I have a function that runs when you click a button. However I don't want the function to execute again until a certain time has passed. For example, the countdown has finished. If the button is clicked again the function should not run.
$("start").on('click', function() {
var myTimer;
function clock() {
myTimer = setInterval(myClock, 1000);
var c = 5;
function myClock() {
document.getElementById("demo").innerHTML = --c;
if (c == 0) {
clearInterval(myTimer);
alert("Reached zero");
}
}
}
});
Firstly remove the clock() function. It serves no purpose given the structure of your code. Secondly, if you're going to use a framework such as jQuery, be consistent with it.
To address the actual issue, store a boolean flag to determine if the time is running or not.
let $demo = $('#demo');
$("#start").on('click', function() {
let $button = $(this);
if ($button.data('running'))
return; // do nothing
$button.data('running', true);
let myTimer = setInterval(myClock, 1000);
let c = 5;
$demo.html(c);
function myClock() {
$("#demo").html(--c);
if (c == 0) {
$button.data('running', false);
clearInterval(myTimer);
console.log("Reached zero");
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button id="start">Start</button>
<div id="demo"></div>

Calling functions one from the other and vice versa

I have two timers with two boolean variables and two functions. The first timer is triggered by a click that put true one of the booleans; once the timer reach some conditions this timer is off setting false the boolean and another timer is triggered setting true the second boolean and calling the second timer.
Same once the second timer reach some conditions, the timer is off setting the second boolean false and I try to trigger the first timer setting the first boolean true and calling the first timer, but it dosn't work.
I cannot call the function that is declared underneath the funcion where I do the call.
My code in JavaScript is:
var active=false;
var activeBreak=false;
...
function breakDown(){
if(activeBreak){
...
if(some conditions){
active=true;
activeBreak=false;
countDown();// **This call doesn't work.Black in jsbin**
}
}
}
function countDown(){
if(active){
...
if(someConditions){
active=false;
activeBreak=true;
breakDown();// *This call works. Blue in jsbin*
}
}
}
...
$("#circle").click(function(){
active=true;
countDown(); // *This call works*/
});
Try
$(document).ready(function(){
/* Global variables */
var state = 'STOPPED';
var timeSession = 1;
var timeBreak = 1;
var timeout = 0;
function resetTimer(time) {
timeout = (new Date()).getTime() + (time*60*1000);
}
function changeState() {
if (state === 'SESSION') {
state = 'BREAK';
resetTimer(timeBreak);
} else if (state === 'BREAK' || state === 'STOPPED') {
state = 'SESSION';
resetTimer(timeSession);
}
$('#text').text(state);
}
/* Function for the countdown ****************************/
function countDown (){
if (state !== 'STOPPED') {
var time = (new Date()).getTime();
if (timeout <= time) {
changeState();
return;
}
var s = Math.floor((timeout - time) / 1000);
var m = Math.floor(s / 60);
s = s - m*60;
$('#timer').text(""+((timeout - time) / 1000)+" "+timeout+" "+m+":"+("0"+s).substr(-2));
}
setTimeout(countDown, 1000);
}
/*****Click Break ********************/
$("#breakMinus").click(function(){
if (timeBreak > 1) {
--timeBreak;
}
$("#breakContent").html(timeBreak);
});
$("#breakPlus").click(function(){
++timeBreak;
$("#breakContent").html(timeBreak);
});
/******Click Session Length****************/
$("#seMinus").click(function(){
if (timeSession > 1) {
--timeSession;
}
$("#seContent").html(timeSession);
});
$("#sePlus").click(function(){
++timeSession;
$("#seContent").html(timeSession);
});
/***********Click circle****************/
$("#circle").click(changeState);
setTimeout(countDown, 1000);
$('#text').text(state);
});

using a function no more then 1 time in 2 sec in javascript

I have a function that starts on mouse wheel scroll but, if i do a longer scroll, it executes for 2-3 times. So i have to find a way to prevent it running if it is called more then 1 time in 2 sec let's say. Any ideas?
PS : this is my function. if you know a better way to start it on scroll and not taking in consideration how long it's the scroll, i would appreciate it as well.
if (window.addEventListener) {
// IE9, Chrome, Safari, Opera
window.addEventListener("mousewheel", MouseWheelHandler, false);
// Firefox
window.addEventListener("DOMMouseScroll", MouseWheelHandler, false);
}
// IE 6/7/8
var s = 0;
function MouseWheelHandler(e) {
// cross-browser wheel delta
var e = window.event || e; // old IE support
var delta = Math.max(-1, Math.min(1, (e.wheelDelta || -e.detail)));
e.preventDefault();
...
}
UPDATE: I worked out my own version of the code, based on the ideas that i've read in the comments and answers. This is it :
function MouseWheelHandler(e) {
var e = window.event || e;
// cross-browser wheel delta
// old IE support
var delta = Math.max(-1, Math.min(1, (e.wheelDelta || -e.detail)));
e.preventDefault();
GoUpDown(delta,e);
}
function GoUpDown(delta,e) {
if(timer ==0){ timer =1;
setTimeout(function () {timer =0;},4200);
/*function stuff*/
}
Here is a simple throttle function. It returns a new function that will only allow the passed in function to run at the specified interval (in milliseconds).
function throttleFunction(func, interval){
return function(){
if(!func.lastRunTime || func.lastRunTime < Date.now() - interval){
func.lastRunTime = Date.now();
func.apply(this, arguments);
}
}
}
Add it into your code like this:
//Only run every 2000 milliseconds
var throttledMouseWheelHandler = throttleFunction(MouseWheelHandler, 2000);
// IE9, Chrome, Safari, Opera
window.addEventListener("mousewheel", throttledMouseWheelHandler , false);
// Firefox
window.addEventListener("DOMMouseScroll", throttledMouseWheelHandler , false);
function throttleFunction(func, interval) {
return function() {
if (!func.lastRunTime || func.lastRunTime < Date.now() - interval) {
func.lastRunTime = Date.now();
func.apply(arguments);
}
}
}
document.body.onclick = throttleFunction(function() {
var div = document.createElement('div');
div.innerHTML = 'clicked';
document.body.appendChild(div);
}, 2000);
<div>Click ME (only registers every 2 seconds)</div>
A throttle way modified from Morten OC's debounce code
http://jsfiddle.net/43sgpme7/13/
var interval = 2000;
var count = 0;
function action() {
count++;
$("p").html(new Date().getTime() + "-" + count)
}
$(".scroll").scroll(function () {
var self = this;
if (this.lastScroll === undefined) {
this.lastScroll = Date.now() - interval;
}
/*calculate how long until next execution should happen*/
var nextTime = interval - Date.now() + this.lastScroll;
/*it doesn't make sense that time range is smaller than 0*/
if (nextTime < 0) {
nextTime = 0;
}
if (this.scrollTo) clearTimeout(this.scrollTo);
this.scrollTo = setTimeout(function () {
self.lastScroll = Date.now();
action();
}, nextTime);
});
For the sake of easy, I included jQuery in this example.. You could rewrite it to native..
Check it out here: http://jsfiddle.net/43sgpme7/
$(".scroll").scroll(function ()
{
if (this.scrollTo) clearTimeout(this.scrollTo);
this.scrollTo = setTimeout(function ()
{
$("p").html(new Date().getTime())
}, 1000);
});

Infinite Loop in Page Redirection Function of JavaScript

I am now working on a piece of code of JavaScript which will be used to redirect a page with a shown counter. The problem is, when counter reaches 0, countDown() function gets in an infinite loop which causes the page to remain the same. And of course, I could not resolve the problem yet. Can anyone help?
You can see the problem here:
http://kibristaodtuvarmis.com/index.html
Code is shown below:
var time = 10;
var page = "http://blog.kibristaodtuvarmis.com";
function countDown()
{
if (time == 0)
{
window.location = page;
return(0);
}
else
{
time--;
gett("container").innerHTML = time;
}
}
function gett(id)
{
if(document.getElementById) return document.getElementById(id);
if(document.all) return document.all.id;
if(document.layers) return document.layers.id;
if(window.opera) return window.opera.id;
}
function init()
{
if(gett("container"))
{
setInterval(countDown, 1000);
gett("container").innerHTML = time;
}
else
{
setTimeout(init, 50);
}
}
document.onload = init();
EDIT:
I have done the below changes in countDown() function and problem is resolved:
var control = false;
function countDown()
{
if (time == 0 && control == false)
{
control = true;
window.location = page;
return(0);
}
else if (time > 0)
{
time--;
gett("container").innerHTML = time;
}
else
{
return(0);
}
}
I would do something like this:
var b = false;
if (time == 0 && b == false)
{
b = true;
window.location = page;
return(0);
}
Try this part of code for by replacing your complete javascript Code :
var time = 10;
var page = "http://blog.kibristaodtuvarmis.com";
function startCount() {
time = time - 1;
console.log(time);
document.getElementById("container").innerHTML = time;
startCounter();
}
function startCounter() {
if (time !== 0) {
setTimeout(function () {
startCount();
},1000);
} else {
location.href = page;
}
}
if (window.addEventListener) {
window.addEventListener("load", startCount, false);
} else if (el.attachEvent) {
window.attachEvent("load", startCount);
}
I tried it, It works.
Tell me your reply after testing.
Are you wanting it to stop at 0? Assign the setInterval to a var and then use clearInterval if 0
your setIinterval continues executing before change the window.location and then causes this loop because time is 0 and should launch window.location again
you should clear the interval
var IdInterval = setInterval(function () {
//.... code
}, 10000);
and after the first execution of countDown with time==0 then:
clearInterval(IdInterval);

How to activate setInterval() incase a text control has the focus

Actually I have an update enquery into this point .
I have smth like that :
$(document).ready(function() {
setInterval(doSmth, 10000);
function doSmth() {
var result = document.getElementById("fooText").value;
if (result != "") {
doSmthElse(result);
}
});
}
}
});
I need to activate the interval ,that is fired each 10 seconds, in case only a text control has the focus else do nothing !!
Code for you is:
$(document).ready(function() {
setInterval(function(){
var result = $("#fooText").val();
if (result != "") {
// if
} else {
// else
}
}, 10000);
You can set the interval on focus of the field, and clear it on blur:
var interval;
$(field).focus(function() {
interval = setInterval(doMsth, 10000);
});
$(field).blur(function() {
clearInterval(interval);
});
(the interval var has to be global)
You can implement this in 2 ways,
Let the timer run and inside the function check if the activeElement == <text input>, then execute the rest of the function else return.
$(document).ready(function() {
setInterval(doSmth, 5000);
function doSmth() {
var resultEl = document.getElementById("fooText");
if (document.activeElement.id != resultEl.id) { return false; }
if (resultEl.value != "") {
doSmthElse(resultEl.value);
}
}
function doSmthElse(result) { alert(result);}
});
DEMO here
Set the timer on focus of the text box and remove the timer onblur of the input box.
$('#fooText').focus ( function () {
timer = setInterval(function() {
var textVal = $('#fooText').val();
if (textVal != '') {
doSmthElse(textVal );
}
}, 5000);
});
$('#fooText').blur (function () {
if (timer != '') clearInterval(timer);
});
DEMO here

Categories

Resources