Javascript clearInterval with button click - javascript

I'm having issues getting clearInterval to work when I try to bind it to a button click. Also, apparently the function is starting on it's own... Here's my code
var funky = setInterval(function() {
alert('hello world');
}, 2000);
$('#start').click(function() {
funky();
});
$('#stop').click(function() {
clearInterval(funky);
});
Here's a js fiddle

You have forgot to add jquery library and have made wrong assignment, it needs to be inside callback function.
Working example:
var funky;
$('#start').click(function() {
funky = setInterval(function() {
alert('hello world');
}, 2000);
});
$('#stop').click(function() {
clearInterval(funky);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button id="start">start</button>
<button id="stop">stop</button>

First off, yes, when you assign a variable to a function, it self invokes.
Secondly, your click events are not working because you need assign the interval to the variable on the click, not invoke the function - there is no function to invoke, as you would see if you looked at your developer console.
Lastly, it is good practice to wrap the jQuery code in the document ready function to ensure all of your event handlers get bound properly.
$(function () {
var funky;
$('#start').click(function() {
funky = setInterval(function() {
alert('hello world');
}, 1000);
});
$('#stop').click(function() {
clearInterval(funky);
});
});

You're saving the wrong value. Try this:
var funky = function() {
alert('hello world');
}
var funkyId = setInterval(funky, 2000);
$('#start').click(function() {
funky();
});
$('#stop').click(function() {
clearInterval(funkyId);
});

Here I am giving you the idea.
declare a variable e.g. let x;
create a function which you want to bind with setInterval.
e.g.
function funky() {
alert("Hello World");
}
assign start.onclick to a function which will assign the setInterval to x.
e.g start.onclick = function(){
clearInterval(x); // to prevent multiple interval if you click more than one
x = setInterval(funky, 2000); // assign the setInterval to x
};
assign stop.onclick to clearInterval(x) to stop the interval.
e.g. stop.onclick = function() {
clearInterval(x); // to stop the interval
};
That's it. Easy right.

Related

clearInterval doesn't work if is in click jquery event?

I want to use clearInterval but I don't know why doesn't work.
var orologio_real; //global variable
$(document).ready(function(){
orologio(1);
$('#change-time').on('click', function(){
clearInterval(orologio_real);
orologio(0);
});
});
function orologio (arg){
orologio_real= setInterval(function(){
alert(arg)
}, 1000);
}
What I don't understand is why if I click on div, clearInterval doesn't work
I think it is a silly mistake. You are setting the time interval all over again inside the click handler. I commented it out, and increased the interval a little so that you get time to click the button
var orologio_real; //global variable
$(document).ready(function(){
orologio(1);
$('#change-time').on('click', function(){
clearInterval(orologio_real);
//orologio(0); //this was the issue
});
});
function orologio (arg){
orologio_real= setInterval(function(){
console.log(arg);
alert(arg);
}, 3000);
}

Calling this inside setTimeout

I Am looking for a way to proper call this inside function now i have quick hack var that = $(this); but i am sure that there is propper way of doing it. How i can avoid this hack?
This is input field which i use to get var and inspect Typing Interval
<input type="text" data-package="pink" class="js-p-input">
this i my code:
var cCalc = (function ($) {
var s;
return {
settings: {
typingTimer: "",
doneTypingInterval: 300,
$inputs: $(".js-p-input"),
},
init: function () {
s = this.settings;
this.bindUIActions();
},
bindUIActions: function () {
//on keyup, start the countdown
s.$inputs.on('keyup', function () {
var that = $(this);
clearTimeout(s.typingTimer);
s.typingTimer = setTimeout(function() {
cCalc.doneTyping(that, that.data("package"));
}, s.doneTypingInterval);
});
s.$inputs.on('keydown', function () {
clearTimeout(s.typingTimer);
});
},
doneTyping: function ($input, packageName) {
console.log('done!');
cCalc.getValues($input.val(), packageName);
},
};
})(jQuery);
cCalc.init();
There is nothing wrong with using that "hack", it is standard operating procedure. See also here What is the difference between call and apply? for even more "hacky" stuff with "this" that is standard.
As others have pointed out, there's not really anything wrong with using a closure but you could alternatively bind "this" into the timeout function scope like so:
s.$inputs.on('keyup', function () {
clearTimeout(s.typingTimer);
s.typingTimer = setTimeout(function() {
cCalc.doneTyping($(this), $(this).data("package"));
}.bind(this), s.doneTypingInterval);
});

Code reuse with different event methods

I have two similar pieces of code in two different functions of my project
and I want to get rid of the repeating code. How can I do that?
1:
getArray("my-hand").forEach(function(elem){
$(elem).mouseover(function(){
$(this).css({'top': '1em'});
});
$(elem).mouseout(function(){
$(this).css({'top': '0em'});
});
$(elem).click(function(){
var cardNode = $(this).get(0);
//some jquery animation
play(cardNode,time);
});
})
and the second piece
2:
getArray("my-hand").forEach(function(elem){
$(elem).mouseover(function(){
$(this).css({'top': '1em'});
});
$(elem).mouseout(function(){
$(this).css({'top': '0em'});
});
$(elem).click(function(){
var cardNode = $(this).get(0);
//a function with another jquery animation
validateCardAndAddForCollection(checkNumber,cardNode,time);
});
})
One way is to put it in a function, and pass as an argument to that function a callback that will execute the desired code:
function handleCards (cb) {
getArray("my-hand").forEach(function(elem){
$(elem).mouseover(function(){
$(this).css({'top': '1em'});
});
$(elem).mouseout(function(){
$(this).css({'top': '0em'});
});
$(elem).click(function(){
var cardNode = $(this).get(0);
//some jquery animation
cb(cardNode);
});
});
}
handleCards(function (cardNode) {
play(cardNode, time);
});
handleCards(function (cardNode) {
validateCardAndAddForCollection(checkNumber,cardNode,time);
});
I'm assuming that the main re-usable logic is the setting up of the events. In that case, I would use a setupHandEvents method to do all of the boring stuff, but pass it a different method to represent it's click handler.
function setupHandEvents (hand, handler){
getArray(hand).forEach(function (elem) {
$(elem).mouseover(function () {
$(this).css({'top': '1em'});
});
$(elem).mouseout(function () {
$(this).css({'top': '0em'});
});
$(elem).click(function (){
handler($(this).get(0));
});
});
}
setupHandEvents('my-hand', function (cardNode) {
play(cardNode, time);
});
setupHandEvents('my-hand', function (cardNode) {
validateCardAndAddForCollection(checkNumber, cardNode, time);
});
Update
You've commented on the other answer that you have these re-used pieces of code wrapped up inside another function (one that delivers variables checkNumber and time from elsewhere. Here is how you would use my setupHandEvents method with the code you posted in that comment:
var func1 = function(time){
setupHandEvents('my-hand', function (cardNode) {
play(cardNode, time);
});
}
var func2 = function(checkNumber, time){
setupHandEvents('my-hand', function (cardNode) {
validateCardAndAddForCollection(checkNumber, cardNode, time);
});
}

$(document).ready() & $(function(){}

I have two functions:
function func1(){}
and
function func2(){}
both of these functions requires the following to work
$(document).ready();
$(window).resize();
so I have implemented it to both the functions as follows:
$(document).ready(func1);
$(window).resize(func1);
and
$(document).ready(func2);
$(window).resize(func2);
The problem? there is two;
1) I already have $(function(){ wrapping the above two functions, but I still need need $(document).ready(); why? isn't both the same thing?!
2) I am trying to short-cut the code and only have $(document).ready();"if needed" and $(window).resize(); to appear once and then add functions to it, and not add it to functions. Confused? okay...
so I basically want to do this:
$(document).ready(func1,func2);
$(window).resize(func1,func2);
But it didn't work, any ideas?
My script:
$(function(){
//Prevent clicking on .active & disabled links
'use strict'; $('.active, disabled').click(function(e) {
e.preventDefault();
});
//Off-canvas menu
var $pages = $('#page, #secondHeader'),
$header = $('#header'),
$secondHeader = $('#secondHeader .menu-button');
$secondHeader.on('touchstart click', function(e) {
e.preventDefault();
$pages.toggleClass("pageOpen");
$header.toggleClass("headerOpen");
$(this).toggleClass("menu-button-active");
});
$('#page').on('touchstart click', function() {
$pages.removeClass("pageOpen");
$header.removeClass('headerOpen');
$secondHeader.removeClass("menu-button-active");
});
//Grid system
var gridElement = $(".gridElement", "#grid3");
(function() {
$(document).ready(GalleryGrid);
$(window).resize(GalleryGrid);
})(jQuery);
function GalleryGrid() {
var grid3 = $('#grid3');
var width = $(window).width();
if (width < 1024 && width > 770) {
var grid1 = $('#grid1');
var grid2 = $('#grid2');
for (var i = 0; i < gridElement.length; i++) {
if (i < gridElement.length / 2) {
grid1.append(gridElement[i]);
} else {
grid2.append(gridElement[i]);
}
}
} else {
grid3.append(gridElement);
}
}
$(document).ready(fullScreen);
$(window).resize(fullScreen);
function fullScreen() {
var newHeight = $("html").height() - $("#header").height() + "px";
$(".fullscreen").css("height", newHeight);
}
});
Use a wrapper function to call both functions on the same event:
function go(){
func1(); // Call function 1 and 2.
func2();
}
$(document).ready(go);
$(window).resize(go);
Or, to make absolutely sure the document is ready, you can even attach the resize event listener after the ready event:
$(document).ready(function(){
$(window).resize(go);
});
Do like this.
function fullScreen() {
var newHeight = $("html").height() - $("#header").height() + "px";
$(".fullscreen").css("height", newHeight);
}
fullScreen();
GalleryGrid();
$(window).resize(function(){
fullScreen();
GalleryGrid();
});
Just call the function like fullScreen() no need to use $(document).ready.
For Gallery Grid
Remove from you code. No need to call (function(){}) twice.
(function() {
$(document).ready(GalleryGrid);
$(window).resize(GalleryGrid);
})(jQuery);
I'd suggest using an anonymous function to get this done.
For example:
$(document).ready(function() {
1();
2();
});
That should be a good starting point.
(function(){ ... })();
It is not equivalent to document.ready. Here it is not necessary DOM is ready. It is anonymous function it invoke itself as soon as possible when the browser is interpreting your ecma-/javascript.
Better and suggested to use document.ready():
$(document).ready(function(){
fullScreen();
//other code
});
Don't
Don't call $(document).ready() inside $(document).ready(), it doesn't make sense. The code inside of $(document).ready(/* the code here */) is not executed immediately. It is scheduled for execution sometime later (when the document is ready).
Calling
$(document).ready(function() {
//do this
$(document).ready(some_function)
//do that
});
Is like saying "wait until the document is ready, do this, wait until the document is ready to do some_function, do that."
Document ready event:
$(function(){})
Is just a shortcut/shorthand for:
$(document).ready(function(){})
ready is an event. It belongs to the document object and it is triggered when the document is ready.
To register two functions to be called when the document is ready just do either:
$(document).ready(function() {
func1();
func2();
});
Or
$(function() {
func1();
func2();
});
Or
function func3() {
func1();
func2();
}
$(document).ready(func3);
Or
function func3() {
func1();
func2();
}
$(func3);
Window resize event:
resize is an event. It belongs to the window object and it is triggered when the window is resized.
To register two functions to be called when the window is resized just do:
$(window).resize(function() {
func1();
func2();
});
Or
function func3() {
func1();
func2();
}
$(window).resize(func3);

Javascript .setTimeout() how to refer to a function

I have these codes:
$(function(){
$('.btn').click(function(){
$title = $(this).attr('title');
$.get('getOutput', {}, function(){
// success ajax get
// how to refer again to this function? Doing again the $('.btn').click event
setTimeout(// $('.btn').click(), 100);
});
});
})
I want to repeat the click event of the button. But my main question is, how would you refer the right function or event in setTimeout() ??
You can wrap it into an anonymous function.
setTimeout(function() {
$('.btn').click();
}, 100);
In case you want to trigger the event in the specific element you've clicked before, you'll need to store the current element in a variable since this value inside the anonymous function would be different.
$('.btn').click(function() {
var $el = $(this);
// ...your code...
setTimeout(function() {
$el.click();
}, 100);
});
You could wrap the time out call back in an anonymous function and just real call the click function in there.
setTimeout(function() {
$(".btn").click();
}, 100);
You can bind this inside the anonymous function with $.proxy() to be compatible with IE8 or use .bind() for modern browers.
setTimeout($.proxy(function(){
// this.click(); // if this = $(".btn")
}, this), 100);
To explain it properly:
$(function(){
var btn = $('.btn');
btn.click(function(ev){
var el = $(ev.currentTarget), // same as $(this) but too many "thisses" can be confusing ^^
title = el.prop('title');
$.get('getOutput', {}, function(){
// success ajax get
// how to refer again to this function? Doing again the $('.btn').click event
setTimeout($.proxy(function(){
this.click();
}, el), 100);
});
});
});
Instead of triggering the click event again, you may be better off naming the click event handler function and calling it again from within your setTimeout.
var handleButtonClick = function() {
$title = $(this).attr('title');
$.get('getOutput', {}, function() {
// success ajax get
setTimeout(handleButtonClick , 100);
});
};
$(function() {
$('.btn').click(handleButtonClick);
});

Categories