I have this jquery functions. I want to make it just one function so I can get thesame results by just calling a function and passing some arguements.
As you can see, the function does basically the same thing counting numbers. I would love to just have one function , then parse out arguments to get the same results. something like startcount(arg1, arg2);
var one_countsArray = [2,4,6,7,4252];
var two_countsArray = [3,3,4,7,1229];
var sumemp = one_countsArray.reduce(add, 0);
var sumallis = two_countsArray.reduce(add, 0);
function add(a, b) {
return a + b;
}
var count = 0;
var inTv = setInterval(function(){startCount()},100);
var inTv2 = setInterval(function(){startCount2()},100);
function startCount()
{
if(count == sumemp) {
clearInterval(inTv);
} else {
count++;
}
$('.stats_em').text(count);
}
var count2 = 10;
function startCount2()
{
if(count2 == sumallis) {
clearInterval(inTv2);
} else {
count2++;
}
$('.stats_iss').text(count2);
}
div {
padding:50px 0;
background: #000000;
color: #ffffff;
width: 100px;
height:100px;
border-radius:50%;
text-align: center;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min.js"></script>
<div class="stats_em"></div>
<div class="stats_iss"></div>
How about a very simple jquery plugin
$.fn.countTo = function(arrNums){
var self = this;
function add(a,b){
return a+b;
}
var current = 0;
var max = arrNums.reduce(add,0);
var int = setInterval(function(){
if(current == max)
clearInterval(int);
else
current++;
self.text(current);
},100);
return this;
}
$('.stats_em').countTo([2,4,6,7,4252]);
$('.stats_iss').countTo([3,3,4,7,1229]);
div {
padding:50px 0;
background: #000000;
color: #ffffff;
width: 100px;
height:100px;
border-radius:50%;
text-align: center;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min.js"></script>
<div class="stats_em"></div>
<div class="stats_iss"></div>
When you notice you're rewriting chunks of similar code, moving to one generic function is the right approach! The best way to start is by trying to determine what you're parameters would be:
count and count2 show that you need a start count for your timer to start at
sumemp and sumpallis show that you need to be able to specify a maximum count
inTv and inTv show that you need to be able to set the interval
$('.stats_iss') and $('.stats_em') show that you need to be able to determine the output element
This means your final class, function or jquery extension will at least have a signature that resembles this:
function(startCount, maximumCount, interval, outputElement) { }
Once you've written this, you can paste in the code you already have. (I've replaced your setInterval with a setTimeout, other than that, not much changed)
var createCounter = function(start, max, interval, outputElement) {
var count = start;
var timeout;
var start = function() {
count += 1;
outputElement.text(count);
if (count < max) {
timeout = setTimeout(start, interval);
}
}
var stop = clearTimeout(timeout);
return {
start: start,
stop: stop
}
}
var one_countsArray = [2, 4, 6, 7, 300];
var two_countsArray = [3, 3, 4, 7, 100];
var sumemp = one_countsArray.reduce(add, 0);
var sumallis = two_countsArray.reduce(add, 0);
function add(a, b) {
return a + b;
}
var counters = [
createCounter(0, sumemp, 100, $('.stats_em')),
createCounter(10, sumallis, 100, $('.stats_iss'))
];
counters.forEach(function(counter) {
counter.start();
});
div {
padding: 50px 0;
background: #000000;
color: #ffffff;
width: 100px;
height: 100px;
border-radius: 50%;
text-align: center;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min.js"></script>
<div class="stats_em"></div>
<div class="stats_iss"></div>
Related
This code fetches multiple words from the same arrays of words and parse it into HTML. Inside the get_word function, how can I avoid the same word from being selected and printed multiple times?
NO: Car, Car, House, Cat
YES: Car, Dog, House, Cat
var words = ["Buss", "Plane", "Car","Dog","Cat", "House"];
get_random = function (list) {
return list[Math.floor((Math.random()*list.length))];
}
get_word = function (number) {
for (i = 1; i < number+1; i++) {
word = get_random(words);
document.getElementById("word"+i).innerHTML = word;
}
}
start = function () {
get_word(3);
}
div.buttons {
text-align: center;
margin: 15px;
}
.button {
background-color: #4CAF50;
/* Green */
border: none;
color: white;
padding: 15px 32px;
text-align: center;
text-decoration: none;
display: inline-block;
font-size: 16px;
}
#word1,
#word2,
#word3,
#word4 {
text-align: center;
font-size: 48px;
color: red;
bottom: 15px;
}
<div id="word1"></div>
<div id="word2"></div>
<div id="word3"></div>
<div id="word4"></div>
<div class="buttons">
<button class="button" onclick="start();">Try it</button>
</div>
I aggree with hoangdv but it can be event simpler
const words = ["Bus", "Plane", "Car","Dog","Cat", "House"];
function shuffle(array) {
array.sort(() => Math.random() - 0.5);
return array
}
get_word = function (number) {
return shuffle(words).slice(0,number)
}
console.log(get_word(3))
console.log(get_word(3))
console.log(get_word(3))
I think the solution to your problem is using pop(), although you will need to make sure that you keep a copy of your original list somewhere if you need to reference it later, as pop will change the list and reduce its length.
This means your function get_random should look closer to:
get_random = function (list)
{
return list.pop(Math.floor((Math.random()*list.length)))
}
I think you can shuffle the array then get get each item of the the shuffled array.
function shuffle(array) {
array.sort(() => Math.random() - 0.5);
}
get_word = function (number) {
shuffle(words);
for (i = 1; i < number+1; i++) {
word = words[i - 1];
document.getElementById("word"+i).innerHTML = word;
}
}
Add an extra variable can resolve the issue.
get_word = function (number) {
var out = [];
for (i = 1; i < number+1; i++) {
word = get_random(words);
if(out.findIndex(w=>w==word) > -1){
out.push(word);
document.getElementById("word"+i).innerHTML = word;
}
}
}
I'm trying to pull through a value from the dataLayer to fire a piece of HTML. All pulling through fine, however if the value is 'undefined' rather than an actual number I don't want it to fire.
How can I solve this? Tried everything but it's returning true/false rather than not firing.
$(document).ready(function () {
for (var i = 0, len = dataLayer.length; i < len; i++) {
if (dataLayer[i].event === "productView")
var viewed = dataLayer[i].P2;
}
function isOnScreen(element) {
var curPos = element.offset();
var curTop = curPos.top - $(window).scrollTop();
var screenHeight = $(window).height();
return (curTop > screenHeight) ? false : true;
}
var intervalId = setInterval(function () {
var addtocart = $('#add-to-cart');
if (isOnScreen(addtocart) === true) {
$('.product-image.main-image').before("<div id='social-overlay' style='color: #fff;text-transform: uppercase;font-family: Muli,Arial,Helvetica,sans-serif; font-size: 11px; font-weight: 800;background: #867dae; opacity: 0.8; padding-top: 10px; padding-bottom: 10px; position: absolute;z-index: 1; width: 100%;'>" + viewed + " people viewed item in the last 24 hours</div>")
setTimeout(function () {
$('#social-overlay').fadeOut(1000);
}, 7000);
clearInterval(intervalId);
}
}, 500);
});
Check if the variable 'viewed' is undefined in the setInterval function you have and add the html value using before function only if the viewed is valid.
var intervalId = setInterval(function() {
var addtocart = $('#add-to-cart');
if ( typeof viewed !== 'undefined' && isOnScreen(addtocart) === true) {
$('.product-image.main-image').before("<div id='social-overlay' style='color: #fff;text-transform: uppercase;font-family: Muli,Arial,Helvetica,sans-serif; font-size: 11px; font-weight: 800;background: #867dae; opacity: 0.8; padding-top: 10px; padding-bottom: 10px; position: absolute;z-index: 1; width: 100%;'>" + viewed + " people viewed item in the last 24 hours</div>") ;
setTimeout(function(){
$('#social-overlay').fadeOut(1000);
}, 7000);
clearInterval(intervalId);
}
}, 500);
I've been wanting to create a timer for my website that countsup, and displays alerts at certain intervals. So like, it starts from 0 and counts upwards when the user pushes a button. From there, it will display a a custom alert at certain intervals... (4 minutes for example)... 45 seconds before that interval, I need the number to change to yellow and 10 seconds before that interval, I need it to change to red... then back to the normal color when it passes that interval.
I've got a basic timer code but I am not sure how to do the rest. I am quite new to this. Any help? Thanks so much in advance.
var pad = function(n) { return (''+n).length<4?pad('0'+n):n; };
jQuery.fn.timer = function() {
var t = this, i = 0;
setInterval(function() {
t.text(pad(i++));
}, 1000);
};
$('#timer').timer();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id='timer'></div>
You could do something like this
var pad = function (n) {
return ('' + n).length < 4 ? pad('0' + n) : n;
};
jQuery.fn.timer = function () {
var t = this,
i = 0;
setInterval(function () {
t.text(pad(i++));
checkTime(i, t);
}, 1000);
};
$('#timer').timer();
checkTime = function (time, t) {
switch (time -1) {
case 10:
t.css('color','red');
break;
case 20:
t.css('color','yellow');
break;
case 30:
t.css('color','green');
break;
case 40:
t.css('color','black');
break;
default:
}
};
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id='timer'></div>
Something like this should work:
Here is a jsFiddle DEMO
jQuery
$.fn.timer = function (complete, warning, danger) {
var $this = $(this);
var total = 0;
$this.text(total);
var intervalComplete = parseInt(complete, 10);
var intervalWarning = parseInt(intervalComplete - warning, 10);
var intervalDanger = parseInt(intervalComplete - danger, 10);
var clock = setInterval(function () {
total += 1;
$this.text(total);
if (intervalWarning === total) {
// set to YELLOW:
$this.addClass('yellow');
}
if (intervalDanger === total) {
// set to RED:
$this.removeClass('yellow').addClass('red');
}
if (intervalComplete === total) {
// reset:
clearInterval(clock);
$this.removeClass();
alert('COMPLETE!');
}
}, 1000);
};
$(function () {
$('#timer').timer(240, 45, 10);
});
CSS
.red {
background-color: red;
}
.yellow {
background-color: yellow;
}
An additional point:
You should place some error validation within the function to ensure your counter completion time is greater than both the warning and danger time intervals.
You can try something like this:
JSFiddle
This is a pure JS timer code. Also for popup you can use something like Bootbox.js.
Code
function timer() {
var time = {
sec: 00,
min: 00,
hr: 00
};
var finalLimit = null,
warnLimit = null,
errorLimit = null;
var max = 59;
var interval = null;
function init(_hr, _min, _sec) {
time["hr"] = _hr ? _hr : 0;
time["min"] = _min ? _min : 0;
time["sec"] = _sec ? _sec : 0;
printAll();
}
function setLimit(fLimit, wLimit, eLimit) {
finalLimit = fLimit;
warnLimit = wLimit;
errorLimit = eLimit;
}
function printAll() {
print("sec");
print("min");
print("hr");
}
function update(str) {
time[str] ++;
time[str] = time[str] % 60;
if (time[str] == 0) {
str == "sec" ? update("min") : update("hr");
}
print(str);
}
function print(str) {
var _time = time[str].toString().length == 1 ? "0" + time[str] : time[str];
document.getElementById("lbl" + str).innerHTML = _time;
}
function validateTimer() {
var c = "";
var secs = time.sec + (time.min * 60) + (time.hr * 60 * 60);
console.log(secs, finalLimit)
if (secs >= finalLimit) {
stopTimer();
} else if (secs >= errorLimit) {
c = "error";
} else if (secs >= warnLimit) {
c = "warn";
} else {
c = "";
}
var element = document.getElementsByTagName("span");
console.log(element, c)
document.getElementById("lblsec").className = c;
}
function startTimer() {
init();
if (interval) stopTimer();
interval = setInterval(function() {
update("sec");
validateTimer();
}, 1000);
}
function stopTimer() {
window.clearInterval(interval);
}
function resetInterval() {
stopTimer();
time["sec"] = time["min"] = time["hr"] = 0;
printAll();
startTimer();
}
return {
'start': startTimer,
'stop': stopTimer,
'reset': resetInterval,
'init': init,
'setLimit': setLimit
}
};
var time = new timer();
function initTimer() {
time.init(0, 0, 0);
}
function startTimer() {
time.start();
time.setLimit(10, 5, 8);
}
function endTimer() {
time.stop();
}
function resetTimer() {
time.reset();
}
span {
border: 1px solid gray;
padding: 5px;
border-radius: 4px;
background: #fff;
}
.timer {
padding: 2px;
margin: 10px;
}
.main {
background: #eee;
padding: 5px;
width: 200px;
text-align: center;
}
.btn {
-webkit-border-radius: 6;
-moz-border-radius: 6;
border-radius: 6px;
color: #ffffff;
font-size: 14px;
background: #2980b9;
text-decoration: none;
transition: 0.4s;
}
.btn:hover {
background: #3cb0fd;
text-decoration: none;
transition: 0.4s;
}
.warn {
background: yellow;
}
.error {
background: red;
}
<div class="main">
<div class="timer"> <span id="lblhr">00</span>
: <span id="lblmin">00</span>
: <span id="lblsec">00</span>
</div>
<button class="btn" onclick="startTimer()">Start</button>
<button class="btn" onclick="endTimer()">Stop</button>
<button class="btn" onclick="resetTimer()">Reset</button>
</div>
Hope it helps!
I have this code:
jQuery/JavaScript
$(document).ready(function () {
function min() {
var number = parseInt($('span').html());
return number - 30;
}
function add() {
var number = parseInt($('span').html());
return number + 31;
}
$("#container").click(function () {
$('span').text(min());
});
$("#box").click(function () {
$('span').text(add());
});
var time = parseInt($('b').html());
if (time <= 0) {
alert("AAAAA");
};
});
CSS
#container{
background: #00ff00;
width: 500px;
height:500px;
}
#box{
background: black;
width: 100px;
height:100px;
color: white;
cursor: pointer;
}
HTML
<div id="container">
<span> 60 </span>
<div id="box"> </div>
</div>
when you click on you text in change for +31 and -30 so you will got 61 because default is 60 and but if you click on text in span will change for -30 only and it will display 30 i wish to alert when text in span reach 0 i made this but didn't work.
does any one know how to fix it?
I think that I'm not understanding completely to you. Maybe this the next link can help you.
You have some errors, check the solution.
$(document).ready(function(){
var $span = $('span');
function min() {
var number = parseInt($span.html());
return number - 30;
}
function add() {
var number = parseInt($span.html());
return number + 31;
}
$("#container").click(function(){
$('span').text(min());
checkTime();
});
$("#box").click(function(){
$('span').text(add());
checkTime();
});
function checkTime() {
debugger
var time = parseInt($span.html());
if (time <= 0) {
alert("AAAAA");
};
}
});
Please next time publish your problem in JSfiddle or similar.
I think you're selector to get the span is incorrect. You also need to execute the check after you decrement the value.
$(document).ready(function(){
function min() {
var number = parseInt($('span').html());
return number - 30;
}
function add() {
var number = parseInt($('span').html());
return number + 31;
}
$("#container").click(function(){
$('span').text(min());
CheckValue();
});
$("#box").click(function(){
$('span').text(add());
});
function CheckValue() {
var val = parseInt($('#container > span').html());
if (val <= 0) {
alert("AAAAA");
}
}
);
I like to display some numbers as pictures. All numbers are included in one picture.
I started with creating a span for each number and each span get a different class so that I can change the picture for the correct number with the style attribute "background-position".
This is working for me. But now I like to add a little animation to this numbers like count up to the correct value. I can do this for one span (number) but how can I do this for all numbers?
HTML:
<style>
.digit0 { background-position: 0 0; }
.digit1 { background-position: 0 -120px; }
.digit2 { background-position: 0 -240px; }
.digit3 { background-position: 0 -360px; }
.digit4 { background-position: 0 -480px; }
.digit5 { background-position: 0 -600px; }
.digit6 { background-position: 0 -720px; }
.digit7 { background-position: 0 -840px; }
.digit8 { background-position: 0 -960px; }
.digit9 { background-position: 0 -1080px; }
</style>
</head>
<body>
<h1>Examples</h1>
<p>
<div id="number">here</div>
</p>
</body>
Javascript:
<script type="text/javascript">
$(document).ready(function(){
// Your code here
var dd = "5487";
dd = dd.replace(/(\d)/g, '<span class="digit0" id="count$1" style="display: inline-block; height: 20px; line-height: 40px; width: 14px; vertical-align: middle; text-align: center; font: 0/0 a; text-shadow: none; background-image: url(../src/jquery.counter-analog.png); color: transparent; margin: 0;"></span>');
$("#number").html(dd);
count = $("#count4").attr("id").replace("count", "").toString();
var i = 0;
setInterval(function() {
counter();
}, 100);
function counter() {
if(i < count) {
i++;
$("#count4").attr("class", "digit" + i + "");
}
}
});
</script>
This is not possible using pure Javascript.
What you're asking for will have to be performed server-side using something like PHP's GD.
Here's one way to do it. It certainly still has room for efficiency and legibility improvement, here and there (see edit history of this answer for one such improvement :) ). But it's a decent start imho:
// goal digits
var dd = '5487';
// separate digits
var digits = dd.split( '' );
// set some animation interval
var interval = 100;
// create spans for each digit,
// append to div#number and initialize animation
digits.forEach( function( value, index ) {
// create a span with initial conditions
var span = $( '<span>', {
'class': 'digit0',
'data': {
'current': 0,
'goal' : value
}
} );
// append span to the div#number
span.appendTo( $( 'div#number' ) );
// call countUp after interval multiplied by the index of this span
setTimeout( function() { countUp.call( span ); }, index * interval );
} );
// count animation function
function countUp()
{
// the current span we're dealing with
var span = this;
// the current value of the span
var current = span.data( 'current' );
// the end goal digit of this span
var goal = span.data( 'goal' );
// increment the digit, if we've not reached the goal yet
if( current < goal )
{
++current;
span.attr( 'class', 'digit' + current );
span.data( 'current', current );
// call countUp again after interval
setTimeout( function() { countUp.call( span ); }, interval );
}
}
See it in action on jsfiddle
To change the speed of the animation, alter the value of interval.
I've answered another similar question some days ago:
$.fn.increment = function (from, to, duration, easing, complete) {
var params = $.speed(duration, easing, complete);
return this.each(function(){
var self = this;
params.step = function(now) {
self.innerText = now << 0;
};
$({number: from}).animate({number: to}, params);
});
};
$('#count').increment(0, 1337);
Update
If you really want to use images, take this:
$.fn.increment = function (x, y, from, to, duration, easing, complete) {
var params = $.speed(duration, easing, complete);
return this.each(function(){
var self = this;
params.step = function(now) {
self.style.backgroundPosition = x * Math.round(now) + 'px ' + y * Math.round(now) + 'px';
};
$({number: from}).animate({number: to}, params);
});
};
$('#count').increment(0, 120, 9);