How to create a persistent random countdown? - javascript

Basically, I need a counter that will go backwards from 100-1 slowly as users enter our website. We are only giving out "100" free coupon but want to give the appearance that users are quickly grabbing them in order to create urgency and have the prospect give us their email. I am using Unbounce to host our mobile landing page.
I came across a similar post to mine but the code generated numbers randomly in the millions. Here is the link for further help: https://stackoverflow.com/a/17964971
Quick example:
Be the first to know when we launch! We are only giving out 100 coupons and there are only (x) amount left.
Click here to get yours!

Count down at a random rate between 5 seconds and 1 second, save the current to the browser so if the user revisits the page the number doesn't reset
(Demo)
var i = 100;
var counter = document.getElementById('counter');
if(localStorage.counter) {
i = localStorage.counter;
}
function countDown() {
if(i > 0) {
i--;
console.log(i);
counter.innerText = i;
localStorage.counter = i;
var timeout = Math.floor(Math.random() * (5000 - 1000)) + 1000;
setTimeout(function(){
countDown();
}, timeout);
} else {
document.getElementById('counter-wrp').innerText = 'Oh no, you missed out! All of the coupons are gone.'
}
}
countDown();
<span id="counter-wrp">Be the first to know when we launch! We are only giving
out 100 coupons and there are only <span id="counter" style="color: red;"></span> left</span>

I create this jsFiddle for you using your example
My method utilizes localStorage, which is perfect for this type of function. You can read more about local storage here w3schools. You need to this save the count.
You will notice that to initialize the counter you need additional options
var counter = new Counter({
start: 123456789,
up: '#btnUp',
down: '#btnDn',
storageKey: 'count'
});
up: and down: are just jQuery selectors for the buttons I added with id's btnUp and btnDn. storagekey: can be whatever string you'd like to set to retrieve our count out of localstorage.
here are my buttons
<div class="buttons">
<button id="btnUp" type="button">+</button>
<button id="btnDn" type="button">-</button>
</div>
I hope this helps

Related

Click event doesn't produce any result

total noob here.
I'm writing a countdown timer that starts clicking on a "Start" button. No matter what I do, the timer always starts at the load of the page. And I mean that, when using live server on VS Code, every time I give the page a save, the timer starts.
No error appears in the console.
Probably I'm missing something really basilar, but I would love some help!
const btnStart = document.querySelector('.start');
const startTimer = function() {
let time = 10;
const timer = setInterval(function() {
const min = String(Math.trunc(time/60));
const sec = String(time%60);
time --;
input.value = `${min.length <= 9 ? min.padStart(2, 0) : min}:${sec.length <= 9 ?sec.padStart (2, 0) : sec}`;
if(time == 0){
setTimeout(function(){clearInterval(timer);
startTimer();}, 1000)
}
}, 1000)
}
btnStart.addEventListener('click', startTimer);
Html elements part:
<div class="main-container">
<input type="text" class="input" placeholder="MM:SS">
<div class="buttons-container">
Start
<button class="start">START</button>
Stop
Reset
</div>
</div>
You new edit to the question answered the question.
You're using VSCode LiveShare. When you save, it doesn't actually reload the page, it just loads the changes.
Since you're recursively calling startTimer(); (it's calling itself inside a setTimeout), it will never stop since it's not a full reload.
The easiest way to fix this is to reload your page manually (Ctrl+r or Command+r)
The harder way you could solve this is to store timer as a global variable, and on load, if timer exists, run clearInterval(timer)

JS: Select any avatar from a folder

So I'm working on some project and in some part of the website, I do need to show random avatar images from a specific folder, each X seconds (I'm using setInterval for this).
BUT the problem is that I can't select random images.
So basically this is a part of my code:
setInterval(function() {
$('#avatar').attr('src', 'assets/img/avatars/*.jpg');
}, 1500);
As you can see, I've tried that *.jpg but it doesn't work.
Do you have any other ideas?
Thank you!
As Rory McCrossan suggested, You can create an array which will contains all the avatar images.
After that in your setInterval function you use the Math.Random to generate a random integer from the given array length and based on that fetch the avatar and show it.
var avatars = [
"img/pic1.jpg",
"img/pic2.jpg",
"img/pic3.jpg",
"img/pic4.jpg",
"img/pic5.jpg"
];
setInterval(function(){
var random = Math.floor(Math.random() * avatars.length);
var item = avatars[random];
$('#avatar').attr('src', item);
$('#avatar').attr('alt', item);
},2000);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<img id="avatar" alt=""/ >

jQuery: How do I check a number from string?

there is a class named:
<div class="level_11 price_level" style="display: block;">
I have a script that runs a browser function.
But I want to run this only when my number in the script is lower than the number from the "level_" div.
I have no idea how to do this.
Well, there are everytime another number. Sometimes level_4, sometimes level_18, etc.
I need to check the number and say if my number is lower then the number from the level_, then run the script.
let setLevel = 3; // Change this to set the building level. Example: let Level = 20 //
let Level = setLevel -1; // Don't touch this //
let logLevel = Level +1; // Don't touch this //
console.log(`Success ✓ - ${IBuilding.length} buildings left`);
$.each(IBuilding, function(Index, Entity) {
let BuildingMissing = IBuilding.length - (Index + 1);
window.setTimeout(function() {
$.get(`/buildings/${Entity.id}/expand_do/credits?level=${Level}`)
console.log(`${BuildingMissing > 0 ? BuildingMissing : 'Success ✓ - last building successfully expanded to level: ' + logLevel }`);
}, Index * 250);
});
});
Basically the script request all sites, and every site have another "level_".
On the sites where the "level_" number is higher than the number in my variable, then dont run the script at the site. but run the script at the sites where my number is higher then the "level_"
Can anyone help me out? :/
You can get the level number like this:
let classname = $("div[class^='level']").attr("class").split(" ").filter(getClass);
function getClass(value) {
return value.startsWith("level_");
}
let level = classname.toString().substr(6);
console.log(level);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="level_11 price_level" style="display: block;">
I found this on link /buildings/ID/:
current level of building
Maybe I can check the Level from there?
The HTML section for that is:
<dd>
13
Ausbauen
</dd>

JavaScript button manipulation according to Time

I'm developing an app and what i want is when the user clicks any button, this button will be hidden and only shows up after 24 hours. Here's what i've done so far.
<div class="buttons">
<p><button onclick="hide();" type="button" name="button" id="button-he">Validar</button></p>
<p><button onclick="hide();" type="button" name="button" id="button-hse">Validar</button></p>
<p><button onclick="hide();" type="button" name="button" id="button-hre">Validar</button></p>
</div>
<script>
function intervalo(){
var but = document.getElementByTagName("button");
but.style.visibility='hidden';
}
</script>
One way to do this is creating a cookie on the button click, that will last for 24 hours, and then check if the button should be clickable. Limitations of this approach will be if the user clears the cookies, the button will then again become clickable.
Take a look at this w3schools example:
https://www.w3schools.com/js/tryit.asp?filename=tryjs_cookie_username
if you want to make sure that the user cant click the button again within 24 hours, you neeed to save this click event server side.
You can use setTimeout( YOUR_FUNCTION, TIME_TO_WAIT )
The setTimeout() method of the WindowOrWorkerGlobalScope mixin (and
successor to window.setTimeout) sets a timer which executes a function
or specified piece of code once after the timer expires.
The time, in milliseconds (thousandths of a second), the timer should
wait before the specified function or code is executed. If this
parameter is omitted, a value of 0 is used, meaning execute
"immediately"
The method takes time in milliseconds so, you need convert your time to milliseconds.
For 24hr you need to pass 24*60*60*1000 as a parameter.
SNIPPET
function hide(but) {
but.style.visibility = 'hidden';
setTimeout(function(btn) {
but.style.visibility = 'visible';
}.bind(this, but), 1000); // Show after 1 second.
// change 1000 to time you want 24*60*60*1000
}
<div class="buttons">
<p><button onclick="hide(this);" type="button" name="button" id="button-he">Validar</button></p>
<p><button onclick="hide(this);" type="button" name="button" id="button-hse">Validar</button></p>
<p><button onclick="hide(this);" type="button" name="button" id="button-hre">Validar</button></p>
</div>
The method will forget the timer if user refreshes the page.
If you want it to be persistent then you can store the timestamp when user clicks the button into localstorage and check if that time exceeded 24hrs on load of page.
Check this fiddle for Implementation
buttons = ["button-he", "button-hse", "button-hre"];
timer = 24 * 60 * 60 * 10000;
function init () {
buttons.forEach(function(val) {
var start = localStorage.getItem(val + '-timer');
var end = new Date().getTime();
var but = document.getElementById(val);
if (start && (end - start < timer)) {
but.style.visibility = 'hidden';
setTimeout(function(btn) {
but.style.visibility = 'visible';
}.bind(this, but), end-start);
}
})
}
init();
window.hide = function(but) {
localStorage.setItem(but.id + '-timer', new Date().getTime());
but.style.visibility = 'hidden';
setTimeout(function(btn) {
but.style.visibility = 'visible';
}.bind(this, but), 24 * 60 * 60 * 10000); // Show after 1 second.
// change 1000 to time you want 24*60*60*1000
}
Although, I suggest also check at the server side for this logic.
For that just pass the time-stamp when user clicks the button to the server and store it and check for time lapse.

Create an infinite loop on field value

So im creating a shop on bigcartel and i want to add a free delivery option. but they currently dont allow you to add it to spercific countries. I am currently adding coding to show a div or alert the user when their total is over £85 and they select UK as their desitination.
ATM i think my code wont loop.. well it dont seem to :/
I need it to loop so that it checks the value of the total price when customers add or subtract items .. whicvh would + or - the total amount.
i HAVE
var amount = {{ cart.total }} ;
var country = {{ store.country | country_select }};
t=setTimeout("checkprice()",10);
function checkprice()
{
if(amount >= 85 || country = 45 )
{
alert('OVER 85!') ;
}
else
{
alert('monkeys')
}
}
EDIT! 08/Feb/12
as suggested by #kolink: i have come up with this,,,
//----get variables--
var amount = {{ cart.total }};
var moose = document.getElementById("country");
function freedel()
{
if (moose = 42 || amount >= 85 )
{
document.getElementById("moose").style.visibility='visible';
}
else
{
alert('WRONG!')
}
}
the HTML being:
<div id="moose" style="visibility:hidden;"> dfgsdgfdsg</div>
and
<h3 id="cart_price" onChange="freedel()">{{ cart.total | money_with_sign }}</h3>
You tell it to check the price 10 milliseconds after the page loads, then you never tell it to run again.
And if your code worked, it would show the alert, then another 10 milliseconds later (which is nowhere near enough time to fix the issue).
What you should do is add checkprice(); to your code wherever you update cart.total or store.country. Maybe an onChange event can help you there.
As a side note, never ever use a string in setTimeout. Pass the function itself (ie. setTimeout(checkprice,10);) or an anonymous function (is. setTimeout(function() {checkprice();},10); instead.

Categories

Resources