Resume a function after clearInterval - javascript

I have this code:
jQuery(function($) { // DOM is ready
var $el = $("header tr"),
tot = $el.length,
c = 0;
var timer = setInterval(function() {
$el.removeClass("current").eq(++c % tot).addClass("current");
}, 3000);
$el.first().addClass("current");
$el.on({
mouseenter: function(e) {
clearInterval(timer);
}
});
$el.mouseout({
timer;
});
});
I want to suspend the function on mouseover and resume it on mouse out but I cant get the latter right. How can I resume it?
Thank you.

There are two ways:
Set a flag that the function being called by the interval checks, and have the function not do anything if it's "suspended."
Start the interval again via a new setInterval call. Note that the old timer value cannot be used for this, you need to pass in the code again.
Example of #1:
jQuery(function($) { // DOM is ready
var $el = $("header tr"),
tot = $el.length,
c = 0,
suspend = false; // The flag
var timer = setInterval(function() {
if (!suspend) { // Check it
$el.removeClass("current").eq(++c % tot).addClass("current");
}
}, 3000);
$el.first().addClass("current");
$el.on({
mouseenter: function(e) {
suspend = true; // Set it
},
mouseleave: function(e) {
suspend = false; // Clear it
}
});
});
Example of #2:
jQuery(function($) { // DOM is ready
var $el = $("header tr"),
tot = $el.length,
c = 0,
timer = 0;
// Move this to a reusable function
var intervalHandler = function() {
$el.removeClass("current").eq(++c % tot).addClass("current");
};
// Probably best to encapsulate the logic for starting it rather
// than repeating that logic
var startInterval = function() {
timer = setInterval(intervalHandler, 3000);
};
// Initial timer
startInterval();
$el.first().addClass("current");
$el.on({
mouseenter: function(e) {
clearInterval(timer); // Stop it
}
mouseleave: function(e) {
startInterval(); // Start it
}
});
});

Checkout these prototypes:
//Initializable
function Initializable(params) {
this.initialize = function(key, def, private) {
if (def !== undefined) {
(!!private ? params : this)[key] = (params[key] !== undefined) ? params[key] : def;
}
};
}
function PeriodicJobHandler(params) {
Initializable.call(this, params);
this.initialize("timeout", 1000, true);
var getTimeout = function() {
return params.timeout;
};
var jobs = [];
function Job(params) {
//expects params.job() function
Initializable.call(this, params);
this.initialize("timeout", getTimeout(), true);
this.initialize("instant", false);
var intervalID = undefined;
this.start = function() {
if (intervalID !== undefined) {
return;
}
if (this.instant) {
params.job(true);
}
intervalID = setInterval(function() {
params.job(false);
}, params.timeout);
};
this.stop = function() {
clearInterval(intervalID);
intervalID = undefined;
};
}
this.addJob = function(params) {
jobs.push(new Job(params));
return jobs.length - 1;
};
this.removeJob = function(index) {
jobs[index].stop();
jobs.splice(index, 1);
};
this.startJob = function(index) {
jobs[index].start();
};
this.stopJob = function(index) {
jobs[index].stop();
};
}
Initializable simplifies member initialization, while PeriodicJobHandler is able to manage jobs in a periodic fashion. Now, let's use it practically:
var pjh = new PeriodicJobHandler({});
//It will run once/second. If you want to change the interval time, just define the timeout property in the object passed to addJob
var jobIndex = pjh.addJob({
instant: true,
job: function() {
$el.removeClass("current").eq(++c % tot).addClass("current");
}
});
jQuery(function($) { // DOM is ready
var $el = $("header tr"),
tot = $el.length,
c = 0;
var timer = setInterval(function() {
$el.removeClass("current").eq(++c % tot).addClass("current");
}, 3000);
$el.first().addClass("current");
$el.on({
mouseenter: function(e) {
jobIndex.stop();
}
});
$el.mouseout({
jobIndex.start();
});
});

With Javascript, it is much easy and efficient.
You can change the interval in setInterval function.
It is checking whether suspend variable is false or true, here suspend variable is setting to true, if mouseEnter function is called and set to false if mouseLeave function is called.
var displayMsg = document.getElementById('msg').innerHTML;
var i = 0;
var suspend = false;
var sequence = setInterval(update, 100);
function update() {
if (suspend == false) {
var dispalyedMsg = '';
dispalyedMsg = displayMsg.substring(i, displayMsg.length);
dispalyedMsg += ' ';
dispalyedMsg += displayMsg.substring(0, i);
document.getElementById('msg').innerHTML = dispalyedMsg;
i++;
if (i > displayMsg.length) {
i = 0;
}
}
}
document.getElementById('msg').addEventListener('mouseenter', mouseEnter);
document.getElementById('msg').addEventListener('mouseleave', mouseLeave);
function mouseEnter() {
suspend = true;
}
function mouseLeave() {
suspend = false;
}
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<style>
#msg {
width: 680px;
height: 100px;
border: 1px solid #ccc;
padding-left: 15px;
}
</style>
</head>
<body>
<div id="msg">
Today is only 15% discount. Hurry up to grab. Sale will end sooooooooooooon!!!!
</div>
<div id="output"></div>
<script src="marquee.js"></script>
</body>
</html>

Related

How to stop function from another function then start it again with another parameter

i am trying to make a slider, i have function that getting array of objects and loop it, and i have select that change models list, but when i change select, old instance of function still work, they are starting to work together. So i add function stopper, but it wont work. Help please, thank you!
var keepGoing = true;
function slideList(models) {
$.each(models, function (index, model) {
setTimeout(function () {
if (keepGoing != false) {
moditem.innerHTML = "";
modlist.value = model.id;
var photo = document.createElement('IMG');
photo.src = model.photos[0].file;
photo.classList.add('img');
moditem.appendChild(photo);
if (index >= models.length - 1) {
slideList(models);
}
} else {
return false;
}
},
5000 * index);
});
}
function startLoop() {
keepGoing = true;
}
function stopLoop() {
keepGoing = false;
}
$("#car-type-select").on('change', function () {
stopLoop();
getModels(this.value);
});
Clear timeout:
var timer;
function slideList(models) {
$.each(models, function (index, model) {
timer = setTimeout(function () {
moditem.innerHTML = "";
modlist.value = model.id;
var photo = document.createElement('IMG');
photo.src = model.photos[0].file;
photo.classList.add('img');
moditem.appendChild(photo);
if (index >= models.length - 1) {
slideList(models);
}
},
5000 * index);
});
}
$("#car-type-select").on('change', function () {
clearTimeout(timer);
getModels(this.value);
});
Other unimportant functions
function getModels(cartype_id) {
$.ajax({
type: 'POST',
url: '/home/models/get',
data: {
'cartype_id': cartype_id
},
success: function (models) {
makeList(models);
slideList(models)
}
});
}
function makeList(models) {
modlist.innerHTML = "";
$.each(models, function (index, model) {
var option = document.createElement("option");
option.text = model.manufacturer.name + ' ' + model.name;
option.value = model.id;
modlist.add(option);
});
}
You need to use clearTimeout to stop function in setTimout to stop executing.
Example:
var timer = setTimeout(function(){ /* code here */ }, 3000)
clearTimeout(timer) //it will stop setTimeout function from executing.
After looking at code update:
Can you please try:
var timers = [];
function slideList(models) {
$.each(models, function(index, model) {
timers.push(setTimeout(function() {
moditem.innerHTML = "";
modlist.value = model.id;
var photo = document.createElement('IMG');
photo.src = model.photos[0].file;
photo.classList.add('img');
moditem.appendChild(photo);
if (index >= models.length - 1) {
slideList(models);
}
},
5000 * index));
});
}
$("#car-type-select").on('change', function() {
$.each(timers, function(i, timer) {
clearTimeout(timer);
})
getModels(this.value);
});
setTimeout is getting called in loop to need array of setTimeout references

javascript How to pause/resume function?

How to pause/resume odometer (so that it pauses/resumes)? I want to be able to pause/resume odometer respectively each time I click .pause-resume button.
This is my code:
https://jsfiddle.net/aht87opr/27/
$('button').click(function() {
var currentvalue = myOdometer.get();
$('#value').text(currentvalue);
});
use setInterval function
var n = 0,
timerID;
var myOdometer;
var div = document.getElementById("odometerDiv");
myOdometer = new Odometer(div, {
value: n,
digits: 6,
tenths: true
});
myOdometer.set(0);
function startcounting() {
timerID = setInterval(function() {
n = n + 0.01
myOdometer.set(n);
}, 200);
}
//]]>
startcounting();
var started = true;
$('button').click(function() {
if (started)
clearTimeout(timerID);
else
startcounting();
started = !started;
var currentvalue = myOdometer.get();
$('#value').text(currentvalue);
});
fiddle
var n = 0;
var timer;
var myOdometer;
function startcounting () {
var div = document.getElementById("odometerDiv");
myOdometer = new Odometer(div, {value: n, digits: 6, tenths: true});
myOdometer.set(0);
update();
}
function update () {
timer = setInterval(function() {
n = n + 0.01
myOdometer.set(n);}, 200);}
startcounting();
var state = true;
$('button').click(function() {
if (state)
clearTimeout(timer);
else
update();
state = !state;
var currentvalue = myOdometer.get();
$('#value').text(currentvalue);
});

Jquery Mobile stopwatch

Im trying to make a stopwatch in a JqueryMobile app. I've been following the guide from a previous post How to create a stopwatch using JavaScript?
This works but the function to create the button, essential just makes 3 links, where as I want them as buttons. So at present it will generate the html of:
start
where as I need it to be
start
I've played around with the function to try to get it to work, and even just added my own buttons into the HTML with hrefs of #start, #stop, #reset but cant get them to work
The function is:
function createButton(action, handler) {
var a = document.createElement("a");
a.href = "#" + action;
a.innerHTML = action;
a.addEventListener("click", function(event) {
handler();
event.preventDefault();
});
return a;
}
Add the classes ui-btn ui-btn-inline to the links in createButton. As you are using jQuery anyway, I hvae also updated the stopwatch to use jQuery for DOM manipulation:
(function($) {
var Stopwatch = function (elem, options) {
var timer = createTimer(),
startButton = createButton("start", start),
stopButton = createButton("stop", stop),
resetButton = createButton("reset", reset),
offset,
clock,
interval;
// default options
options = options || {};
options.delay = options.delay || 1;
var $elem = $(elem);
// append elements
$elem.empty()
.append(timer)
.append(startButton)
.append(stopButton)
.append(resetButton);
// initialize
reset();
// private functions
function createTimer() {
return $('<span class="swTime"></span>');
}
function createButton(action, handler) {
var a = $('<a class="' + action + ' ui-btn ui-btn-inline">' + action + '</a>');
a.on("click",function (event) {
handler();
event.preventDefault();
});
return a;
}
function start() {
if (!interval) {
offset = Date.now();
interval = setInterval(update, options.delay);
}
}
function stop() {
if (interval) {
clearInterval(interval);
interval = null;
}
}
function reset() {
clock = 0;
render();
}
function update() {
clock += delta();
render();
}
function render() {
timer.text(clock / 1000);
}
function delta() {
var now = Date.now(),
d = now - offset;
offset = now;
return d;
}
// public API
this.start = start;
this.stop = stop;
this.reset = reset;
};
$.fn.stopwatch = function(options) {
return this.each(function(idx, elem) {
new Stopwatch(elem, options);
});
};
})(jQuery);
$(document).on("pagecreate","#page1", function(){
$(".stopwatch").stopwatch();
});
DEMO

Trigger a event when the user is on the page

I have this code
$(document).ready(function(){
var fade_in = function(){
$(".quote").fadeIn();
}
setTimeout(fade_in, 2000);
var fade_out = function() {
$(".quote").fadeOut();
}
setTimeout(fade_out, 10000);
});
What it does is that the div "quote" slowly fades in, stays for a few seconds and then fades out. What I want is that all this happens when the user is on the page, if you're not in the page,the text fades in, fades out and you miss it. How can I do that?
There are two ways
First : (bit old)
$(document).ready(function() {
window.onfocus = function() {
var fade_in = function() {
$(".quote").fadeIn();
}
setTimeout(fade_in, 2000);
var fade_out = function() {
$(".quote").fadeOut();
}
setTimeout(fade_out, 10000);
};
});
<script src="//ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="quote">quote</div>
Second :
function getHiddenProp() {
var prefixes = ['webkit', 'moz', 'ms', 'o'];
// if 'hidden' is natively supported just return it
if ('hidden' in document) return 'hidden';
// otherwise loop over all the known prefixes until we find one
for (var i = 0; i < prefixes.length; i++) {
if ((prefixes[i] + 'Hidden') in document)
return prefixes[i] + 'Hidden';
}
// otherwise it's not supported
return null;
}
function isHidden() {
var prop = getHiddenProp();
if (!prop) return false;
return document[prop];
}
// use the property name to generate the prefixed event name
var visProp = getHiddenProp();
if (visProp) {
var evtname = visProp.replace(/[H|h]idden/, '') + 'visibilitychange';
document.addEventListener(evtname, visChange);
}
function visChange() {
var txtFld = document.getElementById('visChangeText');
if (txtFld) {
if (!isHidden()) {
var fade_in = function() {
$(".quote").fadeIn();
}
setTimeout(fade_in, 2000);
var fade_out = function() {
$(".quote").fadeOut();
}
setTimeout(fade_out, 10000);
};
}
}
}
<script src="//ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="quote">quote</div>
This will execute when page div visible
$(document).ready(function(){
$( "div:visible" ).click(function() {
$( this ).css( "background", "yellow" );
});
});

Set and Clear Interval turns into multiple Interval

I am trying to develope a slider, which change every 5 seconds if the user doens´t hit the back- or forward-button.
But if he (the user) does, the interval fires multiple times... why?
I save the Interval in a variable and clear this variable so i don´t know why this dont work... but see yourself:
jQuery.fn.extend({
wrGallery: function() {
return this.each(function() {
// config
var wrClassActive = 'galerie_active';
var wrTime = 5000;
// wrAutomaticDirection gibt an, in welche Richtung
// die Gallerie bei automatischem Wechsel wechseln soll (True = vorwärts/rechts)
var wrAutomaticDirection = true;
var wr = jQuery(this);
var wrGalleryContents = wr.find('.galerie_content');
var wrGalleryContentsFirst = wr.find('.galerie_content:first-child');
var wrBtnBack = wr.find('#galerie_backward');
var wrBtnFor = wr.find('#galerie_forward');
var wrTimer = 0;
var wrI = 0;
var wrOldActiveID = 0;
var wrInit = function() {
wrGalleryContents.each(function() {
wrI++;
jQuery(this).attr('id', wrI);
jQuery(this).css({
display: 'none',
opacity: 0
})
})
wrGalleryContentsFirst.css({
display: 'block',
opacity: 1
})
wrGalleryContentsFirst.addClass('galerie_active')
wrStartTimer();
}
var wrStartTimer = function() {
wrTimer = setInterval(function() {
wrChange(wrAutomaticDirection);
}, wrTime)
}
var wrStoppTimer = function() {
clearInterval(wrTimer);
wrTimer = 0;
}
var wrBackground = function(wrDirection) {
wrOldActiveID = wr.find('.' + wrClassActive).attr('id');
wr.find('.' + wrClassActive).removeClass(wrClassActive);
if (wrDirection) {
wrOldActiveID++;
if (wrOldActiveID <= wrI) {
wr.find('#' + wrOldActiveID).addClass(wrClassActive);
} else {
wr.find('#1').addClass(wrClassActive);
}
} else {
wrOldActiveID--;
if (wrOldActiveID <= wrI) {
wr.find('#' + wrOldActiveID).addClass(wrClassActive);
} else {
wr.find('#3').addClass(wrClassActive);
}
}
}
var wrAnimate = function(wrDirection) {
wrGalleryContents.stop().animate({
opacity: 0
}, 500);
wr.find('.' + wrClassActive).css({
display: 'block'
})
wr.find('.' + wrClassActive).stop().animate({
opacity: 1
}, 500);
}
var wrChange = function(wrDirection) {
wrBackground(wrDirection);
wrAnimate(wrDirection);
}
wr.on('mouseenter', function() {
wrStoppTimer();
});
wr.on('mouseleave', function() {
wrStartTimer();
});
wrBtnBack.on('click', function() {
wrStoppTimer();
wrStartTimer();
wrChange(false);
});
wrBtnFor.on('click', function() {
wrStoppTimer();
wrStartTimer();
wrChange(true);
});
wrInit();
});
}
});
Thanks for reading ;-)
Add a wrStoppTimer() call at the beginning of wrStartTimer:
var wrStartTimer = function() {
wrStoppTimer();
wrTimer = setInterval(function() {
wrChange(wrAutomaticDirection);
}, wrTime)
};
Also in the two click functions you have:
wrStoppTimer();
wrStartTimer();
you can remove that wrStoppTimer() call since wrStartTimer() will call it for you now.
One other thing: if you define functions the way you're doing with var name = function() { ... } you should put a semicolon after the closing } as in the updated code above.

Categories

Resources