views:

116

answers:

3

On this site - LINK - i need to use 3 banner scrollers (2x vertical + 1x horizontal). I've tried to do it in flash, but then everyone web browsers shut down, or suspended. Now i want to do it in JS (i use mootools). All data come from MySQL. Here's the complete code (even if you don't know mootools, You should understand it)

global $wpdb;
$table = $wpdb->prefix.'part';
$sql = "SELECT * FROM $table";
$q = $wpdb->get_results($sql);
$g = 0;
if($wpdb->num_rows > 0)
{
?>
<script type="text/javascript">
window.addEvent('load', function(){
    var totall = 0;
    var totalr = 0;
    $$('#leftCont0 .contElement').each(function(el){
        var img = new Asset.image(el.getFirst('a').getFirst('img').get('src'));
        totall += img.height;
    });
    $$('#rightCont0 .contElement').each(function(el){
        var img = new Asset.image(el.getFirst('a').getFirst('img').get('src'));
        totalr += img.height;
    });

    $$('.leftCont').each(function(el){
        var h = parseInt(el.get('id').substr(8));
        el.setStyle('top', h * totall);
    });
    $$('.rightCont').each(function(el){
        var h = parseInt(el.get('id').substr(9));
        el.setStyle('top', h * totalr);
    });
    var total = new Array(totall, totalr);
    move.periodical(30, null, total);
});
function move(num, num2)
{
    var h = 0;
    var da = false;
    var target = null;
    $$('.leftCont').each(function(el){
        var act = el.getStyle('top');
        var n = parseInt(act)+1;
        el.setStyle('top', n+"px");
        if(el.getStyle('top') < h)
        {
            h = parseInt(el.getStyle('top'));
            alert(h);
        }
        if(parseInt(el.getStyle('top')) > 400)
        {
            da = true;
            target = el;
        }
    });
    if(da)
    {
        var n = h - num;
        target.setStyle('top', n+'px');
    }
    h = 0;
    da = false;
    $$('.rightCont').each(function(el){
        var act = el.getStyle('top');
        var n = parseInt(act)+1;
        el.setStyle('top', n+"px");
        if(el.getStyle('top') < h)
        {
            h = parseInt(el.getStyle('top'));
            alert(h);
        }
        if(parseInt(el.getStyle('top')) > 400)
        {
            da = true;
            target = el;
        }
    });
    if(da)
    {
        var n = h - num2;
        target.setStyle('top', n+'px');
    }
}
</script>
<?php 
$g = 0;
$l = 0;
$r = 0;
$leftContent = array();
$rightContent = array();
$leftHeight = 0;
$rightHeight = 0;
foreach($q as $q)
{
    if(($g % 2) == 0)
    {
        $leftContent[$l] = '<div class="contElement">
                <a href="'.$q->aurl.'"><img src="'.$q->imgurl.'" alt="Partner" /></a>
            </div>';
        $lHeight = getimagesize($q->imgurl);
        $leftHeight .= $lHeight[1];
        $l++;
    }
    else
    {
        $rightContent[$r] = '<div class="contElement">
                <a href="'.$q->aurl.'"><img src="'.$q->imgurl.'" alt="Partner" /></a>
            </div>';
        $rHeight = getimagesize($q->imgurl);
        $rightHeight .= $rHeight[1];
        $r++;
    }
    $g++;
}
$quantity = ceil(400 / $leftHeight) + 1;

for($i = 0; $i < $quantity; $i++)
{
    $str = "";
    for($j = 0; $j < sizeof($leftContent); $j++)
    {
        $str .= $leftContent[$j];
    }
    $leftContainer[$i] = '<div class="leftCont" id="leftCont'.$i.'">'.$str.'</div>';
}

$quantity = ceil(400 / $rightHeight) + 1;

for($i = 0; $i < $quantity; $i++)
{
    $str = "";
    for($j = 0; $j < sizeof($rightContent); $j++)
    {
        $str .= $rightContent[$j];
    }
    $rightContainer[$i] = '<div class="rightCont" id="rightCont'.$i.'">'.$str.'</div>';
}

?>
<div id="pcl">
<?php
for($i = 0; $i < sizeof($leftContainer); $i++)
{
    echo $leftContainer[$i];
}
?>
</div>
<div id="pcr">
<?php
for($i = 0; $i < sizeof($rightContainer); $i++)
{
    echo $rightContainer[$i];
}
?>  
</div>
<?php
}
+1  A: 

Your move() function with two each() loops is expensive to be executed in every 30 milliseconds. Because all your scrolling elements are moving at the same speed / not relatively to each other, you could just animate their root container. I'm pretty sure that would give you 10x boost.

To find out what exactly is eating CPU cycles, use javascript profiler provided by browsers. Safari has got good one, Firebug too.

jholster
+1  A: 

in your move function for instance, several changes can be done that will improve matters.

first, $$('.rightCont') and $$('.leftCont') are selectors that traverse the dom each time you call the function. if you don't expect the array elements to change, why not cache them into global variables, eg:

var conts = {
    left: $$("div.rightCont"),
    right: $$("div.leftCont")
};

// then just refer to them within function move like so...
conts.left.each(...); // etc.

when you setStyle dimensions in mootools default unit is px anyway, there's no sense in concatenating your top (int) and the "px" string, esp IE can slow down here as strings are immutable...

also, if you do stuff like el.setStyle('top', n) then you can assume el.style.top will be n, yet further down you do if(el.getStyle('top') < h) and if(parseInt(el.getStyle('top')) > 400), two senseless lookups.

you can really speed this up by doing a single loop for both types of elements as well, i reckon... anyway, gl.

using el.getPosition().y will arrive as int already so you don't need parseInt (not much cpu saving there as the framework probably does the same anyway). also, when you need parseInt, use mootools' number.toInt() instead, it's chainable

Dimitar Christoff
A: 

Thanks guys, i've connected 3 timers into 1. Now everyone can see change into good way. Dimitar - thanks for showing me those mootools functions - i use only those which i know. Thanks!

Misiur