Clear Angular timeout inside function - javascript

I've built a very simply slider with Angular like so:
$scope.slider = {};
$scope.slider.pane = 1;
$scope.slider.auto = true;
var slider = function(){
$timeout(function(){
if ($scope.slider.pane === 4) $scope.slider.pane = 1;
else $scope.slider.pane ++;
slider();
}, 4000);
}
slider();
The slider function creates a timeout loop to change the value of slider.pane every 4s. In the HTML I have a link that when clicked sets the value slider.auto to false.
Stop slider
When this is clicked, it needs to stop the timeout loop. It may be in the middle of a cycle at the time, so I need to clear the timeout, but it's inside a function so not sure how to access it.

Use the $timeout.cancel function:
var timeout;
$scope.cancelTimer = function() {
$scope.slider.auto=false;
$timeout.cancel(timeout);
};
var slider = function(){
timeout = $timeout(function(){
if ($scope.slider.pane === 4) $scope.slider.pane = 1;
else $scope.slider.pane ++;
slider();
}, 4000);
}
slider();
//HTML
Stop slider

Try:
$scope.slider = {};
$scope.slider.pane = 1;
$scope.slider.auto = true;
var promise;
var slider = function(){
promise = $timeout(function(){
if ($scope.slider.pane === 4) $scope.slider.pane = 1;
else $scope.slider.pane ++;
slider();
}, 4000);
}
$scope.autoSliderFalse = function() {
$scope.slider.auto = false;
if(promise)
$timeout.cancel(promise);
});
slider();
HTML
Stop slider

You can use the cancel method as some people suggested here.
I actually think in your case you should use $interval instead of $timeout.
var interval = $interval(function(){
if ($scope.slider.pane === 4) {
$scope.slider.pane = 1;
}
else {
$scope.slider.pane ++;
}
}, 4000);
$scope.stopSlider = function(){
$interval.cancel(interval);
};
//html
Stop slider

Related

hold down button after 1 second and loop the action using jQuery

I got this code from: Jquery: mousedown effect (while left click is held down)
It is behaving that if I am holding the button in every 50ms it will do something.
var timeout = 0;
$('#button_add').mousedown(function () {
timeout = setInterval(function () {
value_of_something ++;
}, 50);
return false;
});
});
But what I want is to execute this part after holding down the button by 1 second and it will continuously do the action 50ms.
As I said you need to use setTimeout()
var timeout = 0;
$('#button_add').mousedown(function () {
setTimeout(function(){
timeout = setInterval(function () {
value_of_something ++;
}, 50);
} , 1000);
return false;
});
Jsfiddle
Please use this code... You have to clearTimeout when user mouseup :
var timeout = 0;
$('#button_add').mousedown(function() {
oneSecondTimer = setTimeout(function() {
timeout = setInterval(function() {
value_of_something++;
}, 50);
}, 1000);
return false;
});
$("#button_add").mouseup(function() {
clearTimeout(oneSecondTimer);
});

clearinterval() outside of jquery plugin

I create plugin something like this
timer plugin
(function($) {
$.fn.timer = function(options) {
var defaults = {
seconds: 60
};
var options = $.extend(defaults, options);
return this.each(function() {
var seconds = options.seconds;
var $this = $(this);
var timerIntval;
var Timer = {
setTimer : function() {
clearInterval(timerIntval);
if(seconds <= 0) {
alert("timeout");
}else {
timerIntval = setInterval(function(){
return Timer.getTimer();
}, 1000);
}
},
getTimer : function () {
if (seconds <= 0) {
$this.html("0");
} else {
seconds--;
$this.html(seconds);
}
}
}
Timer.setTimer();
});
};
})(jQuery);
and I call the plugin like this.
$(".myTimer").timer({
seconds : 100
});
i called the plugin at timerpage.php. When i changed the page to xxx.php by clicking another menu, the timer interval is still running and i need to the clear the timer interval.
i created a webpage using jquery ajax load. so my page was not refreshing when i change to another menu.
my question is, how to clear the timer interval or destroy the plugin when i click another menu?
Please try with following modifications:
timer plugin:
(function($) {
$.fn.timer = function(options) {
var defaults = {
seconds: 60
};
var options = $.extend(defaults, options);
return this.each(function() {
var seconds = options.seconds;
var $this = $(this);
var timerIntval;
var Timer = {
setTimer : function() {
clearInterval(timerIntval);
if(seconds <= 0) {
alert("timeout");
}else {
timerIntval = setInterval(function(){
return Timer.setTimer();
}, 1000);
$this.data("timerIntvalReference", timerIntval); //saving the timer reference for future use
}
},
getTimer : function () {
if (seconds <= 0) {
$this.html("0");
} else {
seconds--;
$this.html(seconds);
}
}
}
Timer.setTimer();
});
};
})(jQuery);
Now in some other JS code which is going to change the div content
var intervalRef = $(".myTimer").data("timerIntvalReference"); //grab the interval reference
clearInterval(intervalRef); //clear the old interval reference
//code to change the div content on menu change
For clearing timer associated with multiple DOM element, you may check below code:
//iterate ovel all timer element:
$("h3[class^=timer]").each(function(){
var intervalRef = $(this).data("timerIntvalReference"); //grab the interval reference
clearInterval(intervalRef);
});
Hope this will give an idea to deal with this situation.
Instead of var timerIntval; set the variable timerInterval on the window object, then you will have the access this variable until the next refresh.
window.timerIntval = setInterval(function() {
Then when the user clicks on any item menu you can clear it:
$('menu a').click(function() {
clearInterval(window.timerIntval);
});
Live example (with multiple intervals)
$('menu a').click(function(e) {
e.preventDefault();
console.log(window.intervals);
for (var i = 0; i < window.intervals.length; i++) {
clearInterval(window.intervals[i]);
}
});
(function($) {
$.fn.timer = function(options) {
var defaults = {
seconds: 60
};
var options = $.extend(defaults, options);
return this.each(function() {
if (!window.intervals) {
window.intervals = [];
}
var intervalId = -1;
var seconds = options.seconds;
var $this = $(this);
var Timer = {
setTimer : function() {
clearInterval(intervalId);
if(seconds <= 0) {
alert("timeout");
} else {
intervalId = setInterval(function(){
//Timer.getTimer();
return Timer.getTimer();
}, 1000);
window.intervals.push(intervalId);
}
},
getTimer : function () {
if (seconds <= 0) {
$this.html("0");
} else {
seconds--;
$this.html(seconds);
}
}
}
Timer.setTimer();
});
};
})(jQuery);
$(".myTimer").timer({
seconds : 100
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<menu>
Menu 1
</menu>
<div class="myTimer"></div>
<div class="myTimer"></div>
Just notice that it's little bit risky because you can only run it once otherwise the interval id of the second will override the first.

How to set a if else function with onmouseover and onmouseout event on a setInterval with images?

var myImage = document.getElementById("mainImage");
var imageArray = ["_images/1.jpg","_images/2.jpg","_images/3.jpg",
"_images/4.jpg","_images/5.jpg","_images/6.jpg"];
var imageIndex = 0;
function changeImage() {
myImage.setAttribute("src", imageArray[imageIndex]);
imageIndex++;
if (imageIndex >= imageArray.length) {
imageIndex = 0;
}
}
I'm learning fundamental in JS how to get a changing images like a gif, when you onmouseover it, it will stop, then onmouseout, it resume again. I'm struggling on the below part.
var intervalHandler = setInterval(changeImage, 3000);
myImage.onmouseover = function(){
clearInterval(intervalHandler);
}
myImage.onmouseout = function(){
setInterval(changeImage, 3000);
}
This is where you got your example? http://www.w3schools.com/jsref/met_win_cleartimeout.asp
To do it properly:
//Start initially:
var intervalHandler = setTimeout(changeImage, 3000);
myImage.onmouseover = function(){
clearInterval(intervalHandler);
}
myImage.onmouseout = function(){
//reset the variable, so it has the new timeout.
intervalHandler = setInterval(changeImage, 3000);
}
Make sure your setInterval function returns the timeout:
function clearInterval(timeout, period){
return clearTimeout(callback,period);
}
function myStopFunction(timeout) {
clearTimeout(timeout);
}
Btw to make sure you loop indefinitely you want to execute:
intervalHandler = setTimeout(changeImage, 3000);
at the end of your changeImage function.

Clear interval from within a closure

I'm trying to clear an interval when the user hovers over an element and then start it up again when they hover off an element. I think this is a closure but I'm not sure, hopefully my code will make sense what I'm trying to do.
var rotatorInterval = function(elem){
var interval = setInterval(function(){
var active = elem.find('.dot.active');
if(active.is('.dot:last-of-type',elem)){
elem.find('.dot').first().click();
}else{
active.next().click();
}
},6000);
interval;
return interval;
};
if($('.rotator').length){
$('.rotator').each(function(){
var self = $(this);
rotatorInterval(self);
self.find('.slide, .dot').on('mouseenter',function(){
console.log('hovered');
clearInterval(interval);
});
});
}
I tried returning the interval from that closure but when I hovered it said interval (the name of the variable I returned) is not defined, so it's like it didn't return it or something.
You just have to actually return the interval reference somewhere
var rotatorInterval = function (elem) {
var interval = setInterval(function () {
var active = elem.find('.dot.active');
if (active.is('.dot:last-of-type', elem)) {
elem.find('.dot').first().click();
} else {
active.next().click();
}
}, 6000);
return interval;
};
if ($('.rotator').length) {
$('.rotator').each(function () {
var self = $(this);
var return_interval = rotatorInterval(self);
self.find('.slide, .dot').on('mouseenter', function () {
clearInterval(return_interval);
});
});
}

How do I stop and start this function on hover

I want to stop and start a function on the hover of a container div, I tried myLoop.stop(); reset the variable but it doesn't work right... Any Thoughts???
//Continuous Scroll
var nex = 1;
var timeInterval = 1000;
$(".logoContainer").hover(function(){
// Stop Function Here
},function () {
// Start Function Here
})
function myLoop () { // create a loop function
setTimeout(function () { // call a 3s setTimeout when the loop is called
if( cache.isAnimating ) return false;
cache.isAnimating = true;
aux.navigate( 1, $el, $wrapper, settings, cache );
nex++;
if (nex < 100) {
myLoop();
}
}, timeInterval)
}
myLoop();
I suggest placing a flag inside your setTimeout function and change this flag according to the event that you want, take a look at this:
http://api.jquery.com/hover/
Your code might need some refactoring, how about something like this (pseudo-code):
function callThisFunctionEveryXSeconds(){
if(continueFlag){
keepScrolling();
}
}
$(someDiv).mouseenter() { continueFlag = true; }
$(someDiv).mouseleave() { continueFlag = false; }
Use clearTimeout to stop setTimeout.
var nex = 1;
var timeInterval = 1000;
$(".logoContainer").hover(function(){
looper.stop();
},function () {
looper.start();
});
function myLoop () { // create a loop function
var timeout;
this.start = function(){
timeout = setTimeout(function () {
cache.isAnimating = true;
aux.navigate( 1, $el, $wrapper, settings, cache );
nex++;
if (nex < 100) {
myLoop();
}
}, timeInterval);
}
this.stop = function () {
clearTimeout(timeout);
}
}
var looper = new myLoop()
OK here I had to change the variable that ended the function then reset and fire again on mouseout(hoverOut):
//Continuous Scroll
var nex = 1,timeInterval = 1000,loop = 0;
function myLoop () { // create a loop function
setTimeout(function () { // call a 3s setTimeout when the loop is called
if( cache.isAnimating ) return false;
cache.isAnimating = true;
aux.navigate( 1, $el, $wrapper, settings, cache );
nex++;
if (nex < 100) {
myLoop();
}
}, timeInterval)
}
myLoop();
$(".logoContainer").hover(function(){
nex = 100;
},(function(){
nex = 1;
myLoop();
})
);

Categories