views:

69

answers:

5

I need to cache about 100 different selections for animating. The following is sample code. Is there a syntax problem in the second sample? If this isn't the way to cache selections, it's certainly the most popular on the interwebs. So, what am I missing?

note: p in the $.path.bezier(p) below is a correctly declared object passed to jQuery.path.bezier (awesome animation library, by the way)

This works

    $(document).ready(function() {
        animate1();
        animate2();
    })
    function animate1() {
        $('#image1').animate({ path: new $.path.bezier(p) }, 3000);
        setTimeout("animate1()", 3000);
    }
    function animate2() {
        $('#image2').animate({ path: new $.path.bezier(p) }, 3000);
        setTimeout("animate2()", 3000);
    }

This doesn't work

    var $one = $('#image1'); //problem with syntax here??
    var $two = $('#image2');
    $(document).ready(function() {
        animate1();
        animate2();
    })
    function animate1() {
        $one.animate({ path: new $.path.bezier(p) }, 3000);
        setTimeout("animate1()", 3000);
    }
    function animate2() {
        $two.animate({ path: new $.path.bezier(p) }, 3000);
        setTimeout("animate2()", 3000);
    }
+2  A: 
   var one = $('#image1');
   var two = $('#image2');
    $(document).ready(function() {
        animate1();
        animate2();
    })
    function animate1() {
        one.animate({ path: new $.path.bezier(p) }, 3000);
        setTimeout("animate1()", 3000);
    }
    function animate2() {
        two.animate({ path: new $.path.bezier(p) }, 3000);
        setTimeout("animate2()", 3000);
    }

fix

when you do:

   var one = $('#image1');

you're storing the jquery object returned by the selector in the var "one". So you don't need to use $ anymore.

fmsf
forgot to mention i tried this. didn't work either. did you successfully test this?
David
`$one` is just a regular variable name, it has nothing to do with jquery. So changing it to `one` shouldn't do anything.
serg
I thought so--it seemed most interwebs recommendations were to use $one as the variable name as a notation for "this variable, it jquery!"
David
ok just lerned something new :)
fmsf
+2  A: 

Also the variable declarations should be outside, but the selectors should be inside $(document).ready(), maybe those images are not ready yet otherwise?

edit, like this:

var one;
var two;
$(document).ready(function() {
     one = $('#image1');
     two = $('#image2'); 
     animate1();
     animate2();
})
dain
if i make those declarations inside `$(document).ready()...` the objects won't be defined in the animate1() and animate2() functions. wait...is that what you meant?
David
+4  A: 

If the images are not loaded when you call them, jQuery will return an empty object. Move your assignment inside your document.ready function:

$(document).ready(function() {
    var $one = $('#image1');
    var $two = $('#image2');
    animate1();
    animate2();
});
// ... etc.

If you need to cache them for later use outside of your initialization script then add them to a storage object:

var my_storage_object = {};
$(document).ready(function() {
    var my_storage_object.$one = $one = $('#image1');
    var my_storage_object.$two = $two = $('#image2');
    animate1();
    animate2();
});
// ... etc.

Then later on, outside of document.ready you can call:

my_storage_object.$one //still has a reference to the jQuery object.
Sean Vieira
BAM--you win. thanks
David
You are most welcome David!
Sean Vieira
+2  A: 

Try this:

var $one;
var $two;
$(document).ready(function() {
    $one = $('#image1');
    $two = $('#image2');
    animate1();
    animate2();
})
function animate1() {
    $one.animate({ path: new $.path.bezier(p) }, 3000);
    setTimeout("animate1()", 3000);
}
function animate2() {
    $two.animate({ path: new $.path.bezier(p) }, 3000);
    setTimeout("animate2()", 3000);
}

The variables are defined in global scope, but the selectors are executed when the document is ready.

marapet
I was just about to post this, but this one has the right solution. The trouble is that your declarations for $one and $two are happening before your DOM is built. Your code would work if you moved it to the bottom of the Body, but this code is another great approach.
g.d.d.c
agreed, i forgot about scope. you get upvote too :)
David
A: 

Your jQuery selectors always need to be inside the .ready() block, so why not put everything there? That way you leave nothing in the global scope.

$(document).ready(function() {
    var storedGlobals = {
        $one: $('#image1'),
        $two: $('#image2')
    };
    animate1(); 
    animate2(); 

    function animate1() { 
        storedGlobals.$one.animate({ path: new $.path.bezier(p) }, 3000); 
        setTimeout("animate1()", 3000); 
    } 
    function animate2() { 
        storedGlobals.$two.animate({ path: new $.path.bezier(p) }, 3000); 
        setTimeout("animate2()", 3000); 
    }
});
jasongetsdown