0

I'm working on a project that will feature many of these 'second by second' timers that will display how many animals are born per second :) Do you have any suggestions as to how I could best optimize this script for performance and DRY-ish?

JSFiddle here - http://jsfiddle.net/gJy4x/32/

var start = new Date(),
midnight = new Date(start.getFullYear(), start.getMonth(), start.getDate(), 0),
first = new Date(start.getFullYear(), start.getMonth(), 1);

setInterval(function () {
    var now = new Date(),
        secondsFromStart = Math.floor((now - start)/1000),
        secondsFromMidnight = Math.floor((now - midnight)/1000),
        secondsFromFirst = Math.floor((now - first)/1000),
        puppiesBornPerSec = 3.16,
        puppiesStart = Math.round(secondsFromStart*puppiesBornPerSec*100) / 100,
        puppiesMidnight = Math.round(secondsFromMidnight*puppiesBornPerSec*100) / 100,
        puppiesFirst = Math.round(secondsFromFirst*puppiesBornPerSec*100) / 100;

    // 3 puppies born every second
    $('#badge01').text(puppiesStart.toFixed(2));
    $('#s01 .morning').text(puppiesMidnight.toFixed(2));
    $('#s01 .month').text(puppiesFirst.toFixed(2));

    // 5 kittens born every second 
    $('#badge02').text(Math.floor(secondsFromStart*5));
    $('#s02 .morning').text(Math.floor(secondsFromMidnight*5));
    $('#s02 .month').text(Math.floor(secondsFromFirst*5));

    // 7 rats born every second
    $('#badge03').text(Math.floor(secondsFromStart*7));
    $('#s03 .morning').text(Math.floor(secondsFromMidnight*7));
    $('#s03 .month').text(Math.floor(secondsFromFirst*7));
}, 1000);
Les Ballard
  • 283
  • 1
  • 4
  • 17

2 Answers2

0

the solution with data that omit the decimals on integer will be like this
you need to add a class in this case "s" and data-quantity

<section class="s" data-quantity="3.16" id="s01">
    <h1>if 3.16 puppies are born every second</h1>
    <b id="badge01" class="now">0</b> puppies have been born so far.<br>
    <b class="morning">?</b> puppies have been born today<br>
    <b class="month">?</b> puppies have been born since the first of this month.
</section>
<hr>
<section class="s" data-quantity="5" id="s02">
    <h1>if 5 kittens are born every second</h1>
    <b id="badge02" class="now">0</b> kittens have been born so far.<br>
    <b class="morning">?</b> kittens have been born today<br>
    <b class="month">?</b> kittens have been born since the first of this month.
</section>
<hr>
<section class="s" data-quantity="7" id="s03">
    <h1>if 7 rats are born every second</h1>
    <b id="badge03" class="now">0</b> rats have been born so far.<br>
    <b class="morning">?</b> rats have been born today<br>
    <b class="month">?</b> rats have been born since the first of this month.
</section>     

JS

var start = new Date(),
midnight = new Date(start.getFullYear(), start.getMonth(), start.getDate(), 0),
first = new Date(start.getFullYear(), start.getMonth(), 1);
//create now Date outside Interval
var now = new Date(),
secondsFromStart = Math.floor((now - start)/1000),
secondsFromMidnight = Math.floor((now - midnight)/1000),
secondsFromFirst = Math.floor((now - first)/1000);
//create each $(".s").data with the values
$(".s").each(function(){
    var BornPerSec = $(this).data("quantity"),
    Start = secondsFromStart*BornPerSec,
    Midnight = secondsFromMidnight*BornPerSec,
    First = secondsFromFirst*BornPerSec;
    $(this).data("persec",{"BornPerSec":BornPerSec,"Start":Start,"Midnight":Midnight,"First":First});    
});
setInterval(function () {
    //increment each $(".s").data values and set .text
    $(".s").each(function(){
        var persec=$(this).data("persec");
        persec.Start+=persec.BornPerSec;
        persec.Midnight+=persec.BornPerSec;
        persec.First+=persec.BornPerSec;
        $(this).children('.now').text(persec.Start % 1 === 0 ?persec.Start: persec.Start.toFixed(2));
        $(this).children('.morning').text(persec.Midnight % 1 === 0 ?persec.Midnight:persec.Midnight.toFixed(2));
        $(this).children('.month').text(persec.First % 1 === 0 ?persec.First:persec.First.toFixed(2));
    });
}, 1000);    

http://jsfiddle.net/gJy4x/34/

Abraham Uribe
  • 3,118
  • 7
  • 26
  • 34
  • Great! One more question how would you go about integrating @thanh's suggestion beow of caching everything inside the loop? – Les Ballard Dec 01 '13 at 19:34
0

In addition to Abraham's script, for best optimization, everything inside a loop should be cached if possible. Such as $(".s"), .children('.now') are executed many times

//cache them
var elems = [];
$(".s").each(function(){
   var $this = $(this);
   elems.push({
      obj: $this,
      data: $this.data('persec'),
      now: $this.children('.now'),
      morning: $this.children('.morning'),
      month: $this.children('.month'),
   });
});
Thanh Trung
  • 3,566
  • 3
  • 31
  • 42