The purpose of the code below is to alert online shoppers that they must select a color (via a select/option menu) before putting an item into their basket. If they don't select a color (ie, make a selection) some blinking text displays alerting them.
I'm trying to have the text blink 3 times then stop. I tried using some counter vars but didn't work. How can I re-write this so the blink executes 3 times only?
function blink() {
if ($('.pleaseSelect').css('visibility') == 'hidden') {
$('.pleaseSelect').css('visibility', 'visible');
} else {
$('.pleaseSelect').css('visibility', 'hidden')
}
}
function showNotice() {
timerId = setInterval(blink, 200);
}
$('#addToCart').click(function() {
if ($("select > option:first").is(":selected")) {
showNotice();
} else {
clearInterval(showNotice);
$('.pleaseSelect').css('visibility', 'hidden');
}
})
Well you can have counter declared and incremented each time blink is called. then check if you have called blink three times, clear the interval. Also your showNotice function is not defined properly.
var counter = 0,
timerId;
function blink() {
if ($('.pleaseSelect').css('visibility') == 'hidden') {
$('.pleaseSelect').css('visibility', 'visible');
} else {
$('.pleaseSelect').css('visibility', 'hidden')
if (counter > 4) {
showNotice(false);
}
}
counter++;
}
function showNotice(show) {
if (show) {
timerId = setInterval(blink, 200);
} else {
clearInterval(timerId);
counter = 0;
}
}
$('#addToCart').click(function () {
if ($("select > option:first").is(":selected")) {
showNotice(true);
} else {
showNotice(false);
$('.pleaseSelect').css('visibility', 'hidden');
}
})
Here is working fiddle
function blink(){
var blinkCount = 0;
return function () {
if($('.pleaseSelect').css('visibility')== 'hidden'){
$('.pleaseSelect').css('visibility', 'visible');
} else {
$('.pleaseSelect').css('visibility', 'hidden')
}
blinkCount = blinkCount + 1;
if (blinkCount === 3) {
clearInterval(timerId);
}
}
}
the only thing is that timeId is global - bad practice... however you would have to refactor more of your code in order to correct that issue.
another option is to just fadIn and fadeOut rather than what you're doing.
It would look something like:
if(element.val() == ''){
element.fadeOut("fast");
element.fadeIn("fast");
element.fadeOut("fast");
element.fadeIn("fast");
element.fadeOut("fast");
element.fadeIn("fast");
}
How about this example? Use an anonymous function to call your blink method and keep decrementing a counter.
id = setInterval(function () {
counter--;
if (!counter) {
clearInterval(id);
}
blink();
}, 200);
See the JSFiddle for the complete context.
You can accomplish the desired behavior using variables within a private scope:
$('#addToCart').click(function(e) {
blink(e);
});
function blink(e) {
var blink_count = 0;
var timer = setInterval(function(e) {
blink_count++;
$('.pleaseSelect').toggle();
if (blink_count >= 6) {
clearInterval(timer);
blink_count = 0;
}
}, 200);
}
Related
The Situation
I have a function which is called on button click and which should draw an animated chart, updating the chart every 2 seconds. When the user clicks that button again, while the animation is still running, the animation should stop.
My current solution
Right now I have the following script which stops the animation visually, but the underlying for-loop continues until the end in the background:
var animRun = false;
$("#animateButton").on("click", function() {
if (animRun === false) {
redraw(data.slice(0,30))
//some CSS...
} else {
//Some CSS...
animRun = false;
}
});
function redraw(data) {
animRun = true;
for (var i=0; i<data.length;i++){
(function(i){
setTimeout(function(){
if(animRun === true) {
//draw the chart
return draw(data[i])
}
},2000*(i))
if (i === data.length -1) {
//reset animRun
if(animRun === true) {
//Some CSS things
//...
animRun = false;
}
}
})(i);
}
}
Question
What would be the correct way of stopping the for-loop when the user clicks the button again while the animation is still executing?
Did you try clearTimeout. Store your draw timeout to an array, and stop it when you done
var animRun = false;
var drawArr = [];
$("#animateButton").on("click", function() {
if (animRun === false) {
redraw(data.slice(0,30))
//some CSS...
} else {
//Some CSS...
animRun = false;
drawArr.forEach(d=>clearTimeout(d));
}
});
function redraw(data) {
animRun = true;
for (var i=0; i<data.length;i++){
(function(i){
drawArr[i] = setTimeout(function(){
if(animRun === true) {
//draw the chart
return draw(data[i])
}
},2000*(i))
if (i === data.length -1) {
//reset animRun
if(animRun === true) {
//Some CSS things
//...
animRun = false;
}
}
})(i);
}
}
I have this function that will show a LOADING image when page is loading:
<script>
function onReady(callback) {
var intervalID = window.setInterval(checkReady, 1000);
function checkReady() {
if (document.getElementsByTagName('body')[0] !== undefined) {
window.clearInterval(intervalID);
callback.call(this);
}
}
}
function show(id, value) {
document.getElementById(id).style.display = value ? 'block' : 'none';
}
onReady(function () {
show('all', true);
show('loading', false);
});
</script>
jsfiddle
What I want to do is add a fadeIn effect to show div #all WHEN LOADING is complete.
Can I add a fadeIn effect in function show? Can I use jquery? Any ideas?
You can use following to function for fade in & fade out effect using javascript. CREDIT
function fadeIn(el, display) {
el.style.opacity = 0;
el.style.display = display || "block";
(function fade() {
var val = parseFloat(el.style.opacity);
if (!((val += .01) > 1)) {
el.style.opacity = val;
requestAnimationFrame(fade);
}
})();
}
function fadeOut(el) {
el.style.opacity = 1;
(function fade() {
if ((el.style.opacity -= .01) < 0) {
el.style.display = "none";
} else {
requestAnimationFrame(fade);
}
})();
}
And change your show function to following.
function show(id, value) {
var el = document.getElementById(id);
if(value)
fadeIn(el)
else
fadeOut(el);
}
UPDATED FIDDLE
You can use jQuery's fadeIn method. e.g
function show(id, value) {
if(value){
$("#" + id).fadeIn(2000);
} else{
$('#' +id).hide();
}
}
https://jsfiddle.net/az9uaspr/
Put this in your "head" tag:
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.0/jquery.min.js"></script>
And Just change your show() like this:-
function show(id, value) {
if(value)
$("#"+id).fadeIn("2000");
else
$("#"+id).hide();
}
I am trying to create a function that loops infinitely until user inputs that they would like to exit. Every time I open up the webpage in the browser, however, no prompt box appears and the infiniteLoop() function does not execute. Why is the infiniteLoop() function not being called?
function infiniteLoop() {
i= 0;
var begin= prompt("Shall we begin?");
if (begin == "Yes") {
var tryAgain= prompt("Exit loop?");
if (tryAgain != "Yes") {
infiniteLoop();
}
}
}
You need to call the function in the window onload event.
window.onload = function(){
infiniteLoop();
}
or, if you're using jquery
$(function() {
infiniteLoop();
});
The prompt box doesn't appear because you didn't call the function when your web page loads.
Add infiniteLoop() after you declare your function.
e.g.
function infiniteLoop() {
i= 0;
var begin= prompt("Shall we begin?");
if (begin == "Yes") {
while (i < 5) {
var tryAgain= prompt("Are you sure?");
if (tryAgain == "Yes") {
i++;
}
else {
infiniteLoop();
}
}
}
else {
infiniteLoop();
}
}
// Initial call
infiniteLoop();
IT WORKS, write 5 times "Yes"(case sensitive) it finishes, otherwise it works infinitely, and do not forget to call infiniteLoop()
Cleaned up and working
(function infiniteLoop() {
var begin = prompt("Shall we begin?");
if (begin === "Yes") {
var i= 0;
while (i < 5) {
var tryAgain = prompt("Are you sure?");
if (tryAgain === "Yes") {
i++;
}
else {
infiniteLoop();
}
}
}
else {
infiniteLoop();
}
})()
This works, but the problem is it works only one time -- and then class ('active') is never added again -- it needs to be removed after 5 clicks as as done with the below, but after 5 it needs to reset and I would like the counter to go back to 0 so that after another 5 clicks it could work again!
var clickCount = 0;
$(".arrowRight").click(function () {
clickCount++;
if (clickCount >= 5)
// alert ("stop it!");
$(".arrowRight").removeClass("active");
else {
$(".arrowRight").addClass("active");
}
});
just set clickCount = 0 in the if statement
if (clickCount >= 5)
clickCount = 0;
$(".arrowRight").removeClass("active");
else {
$(".arrowRight").addClass("active");
}
Will something like this work?
var clickCount = 0;
$(".arrowRight").click(function () {
clickCount++;
if (clickCount >= 5) {
clickCount = 0;
$(".arrowRight").removeClass("active");
}
else {
$(".arrowRight").addClass("active");
}
});
This is another option:
if (clickCount%5==0) {
$(".arrowRight").removeClass("active");
} else {
$(".arrowRight").addClass("active");
}
I'm trying to make this blinking text stop after 3 seconds (or 3-5 blinks). I've set the blink rate to about the right speed, but cannot figure out how to make it stop.
Here's the code:
$('.blink').each(function() {
var elem = $(this);
setInterval(function() {
if (elem.css('visibility') == 'hidden') {
elem.css('visibility', 'visible');
} else {
elem.css('visibility', 'hidden');
}
}, 200);
});
Any suggestions?
I've compiled a jQuery fiddle here: http://jsfiddle.net/M4Fcd/173/
setInterval goes on indefinitely - or until stopped.
What you need to do is capture the intervalID when you create the interval and then clear the interval after you are done with it
var intervalID = setInterval(function....);
// when done
clearInterval(intervalID);
In your particular case:
$('.blink').each(function() {
var elem = $(this);
// count the blinks
var count = 1;
var intervalId = setInterval(function() {
if (elem.css('visibility') == 'hidden') {
elem.css('visibility', 'visible');
// increment counter when showing to count # of blinks and stop when visible
if (count++ === 3) {
clearInterval(intervalId);
}
} else {
elem.css('visibility', 'hidden');
}
}, 200);
});
Updated fiddle http://jsfiddle.net/M4Fcd/186/
You could also use fadeIn/fadeOut like this
$('.blink').each(function() {
var elem = $(this);
elem.fadeOut(100)
.fadeIn(100)
.fadeOut(100)
.fadeIn(100)
.fadeOut(100)
.fadeIn(100);
});
jsFiddle
$('.blink').each(function() {
var elem = $(this);
refreshIntervalId = setInterval(function() {
if (elem.css('visibility') == 'hidden') {
elem.css('visibility', 'visible');
} else {
elem.css('visibility', 'hidden');
}
}, 200);
});
setTimeout(function(){
clearInterval(refreshIntervalId);
}, 3000)
fiddle: http://jsfiddle.net/M4Fcd/176/
try this:
var i = 0;
var blink;
$('.blink').each(function() {
var elem = $(this);
blink = setInterval(function() {
if (elem.css('visibility') == 'hidden') {
elem.css('visibility', 'visible');
i++;
if(i >= 3){
clearInterval(blink);
}
} else {
elem.css('visibility', 'hidden');
}
}, 200);
});
Fiddle
Ok, there is better way. You can just toggle css class with visibility: hidden, the code gets simpler and than if you want to stop when visible/not visible just need to check with hasClass.
$('.blink').each(function() {
var elem = $(this),
timer = 0,
interval = 200,
stopAfter = 3000,
intervalId = setInterval(function() {
elem.toggleClass('blink');
if(timer > stopAfter && !elem.hasClass('blink')) {
clearInterval(intervalId);
}
timer += interval;
}, interval);
});
fiddle: http://jsfiddle.net/M4Fcd/183/
Now you can stop it when it's visible or not, but the idea is pretty the same.
$('.blink').each(function() {
var elem = $(this),
timer = 0,
interval = 200,
stopAfter = 3000;
refreshIntervalId = setInterval(function() {
if (elem.css('visibility') == 'hidden') {
elem.css('visibility', 'visible');
if(timer > stopAfter) {
clearInterval(refreshIntervalId);
}
} else {
elem.css('visibility', 'hidden');
}
timer += interval;
}, interval);
});
fiddle: http://jsfiddle.net/M4Fcd/180/
I think I have the shortest answer.
function blinkElement(elm, interval, duration) {
elm.style.visibility = (elm.style.visibility === "hidden" ? "visible" : "hidden");
if (duration > 0) {
setTimeout(blinkElement, interval, elm, interval, duration - interval);
} else {
elm.style.visibility = "visible";
}
}
To blink for 3 seconds in the rate of 200 milliseconds.
blinkElement(element, 200, 3000);