views:

4000

answers:

4

I have a nested function to show/hide paragraphs news-ticker-style.

The problem is that when the loop starts over (line 4), the opacity effects stop working correctly so the paragraphs appear abruptly.

Any jquery masters know about this? Am I making this too hard?

$('#special-ticker p').hide();
var a=0;
function outer() {
    function inner() {
        if(a===$('#special-ticker p').length) { a = 0; }
        $('#special-ticker p').
        eq(a).
        fadeIn(800, function(){
            $(this).animate({opacity:100},10000,null,function(){
                $(this).hide(800,function(){
                    a++;
                    outer();
                });
            });
        });
    }
    return inner();
}
$(function(){ 
    outer(); 
});
+5  A: 

the problem is line 9:

$(this).animate({opacity:100},10000,null,function(){
//...

opacity should be "1" (opacity is a value between 0 and 1)

$(this).animate({ opacity : 1 }, 10000, null, function() {
Owen
The animate method has nothing to do with opacity. It's only used as a delay for controlling how long to displaying the text before hiding.
Jason Moore
it's not animate that's the issue, it's setting opacity to 100, which is not a valid result, opacity is a value between 0 and 1. copy and test his code as is, then change the opacity to 1 as in my example, you'll see the abrupt animation stoppage that he mentions will disappear.
Owen
Arg that's so obvious! Thanks very much!
willoller
+1  A: 

Try this:


      newsticker = function (selector) {
       $(selector).hide();
       var i = $(selector).length - 1;
       var toggle = function() {
        $(selector).eq(i).fadeOut("slow", function() {
         i = ++i % $(selector).length;
         $(selector).eq(i).fadeIn("slow", function() {
          setTimeout(toggle, 1000)
         });

        });
       };   
       toggle();
      };

and initialize it with this:


      new newsticker("#special-ticker p");
Andy
nice solution. To the OP: if you really want to keep the wipe effect, just change the first "fadeOut" to "hide".
Jason Moore
+1  A: 

Solution has been posted, but one comment:

If a group of elements are going to be hidden immediately, it is faster to create a "hidden" CSS class and then assign it to those elements. Saves a bit of javascript code, but also ensures that the hidden elements won't be briefly flashed on screen.

<style type="text/css" media="screen">
.hidden { display: none; }
</style>

<p>Show me</p>
<p class="big hidden">Use javascript to show me later.</p>
Jason Moore
Good point. If you are using this technique, you should consider using javascript to create the css (for graceful degradation).
willoller
A: 

A slight reworking of the code to save repeatedly creating jQuery instances with the same selectors. I think it's a little easier to read, too.

var jS = $('#special-ticker p');
// jS.hide(); // not needed if css hides elements initially
var i = 0;

function do_ticker() {
  jS.eq(i).fadeIn(800, function() {
    var me = $(this);     
    setTimeout(function() { me.hide(800, 
      function() { 
        i = ++i % jS.length;
        do_ticker();
      });
    },1000); // setTimeout
  });
};
do_ticker();
Jason Moore