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
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);
});
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.
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.
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);
});
});
}
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();
})
);