0

Despite all the posts on SO re blinking text, I didn't find a perfect solution. Most blink the text by hiding it - which means the user cannot reliably click on it (during the hidden cycle, it is not clickable).

I've scraped bits and pieces from other examples to create the beginnings of a solution, but I'm having difficulty with the parameters.

DESIRED:

$('#selector').click(function() {
    blink(this, speed, iterations); //iterations==0 for unlimited iterations
});

PROBLEM:

  • Blinking does not stop after desired number of iterations (or 0 for blink forever).

Note that I do not wish to use .hide, .toggle, .fade or any other jQ method that renders the div unclickable during the "invisible" period of the blinking cycle.

Here's the code I have so far: jsFiddle

<html>
    <head>
        <script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>

        <script type="text/javascript">
            $(document).ready(function() {

                var pad = 0;

                $('#clignotant').click(function() {
                    if (pad==0) {
                        pad++;
                        blink(this, 800, 15);
                    }else{
                        alert('Not document.load, so now send user to the streaming video');
                    }
                });

                function blink(selector, blink_speed, iterations){
                    counter = 0;
                    $(selector).animate({opacity:0}, 50, "linear", function(){
                        $(this).delay(blink_speed);
                        $(this).animate({opacity:1}, 50, function(){
                            if (iterations == 0) {
                                blink(this, blink_speed, iterations);
                            }else if (counter>iterations) {
                                return false;
                            }else{
                                counter++;
                                blink(this, blink_speed, iterations);
                            }
                        });
                        $(this).delay(blink_speed);
                    });
                }

                //This line must come *AFTER* the $('#clignotant').click() function !!
                window.load($('#clignotant').trigger('click'));


            }); //END $(document).ready()

        </script>
    </head>
<body>

    <div id="clignotant" style="background-color:#FF6666;width:500px;
    height:100px;line-height:100px;text-align:center;">
        This box, and the text in it, are blinking
    </div>

</body>
</html>

Sources:
Moses Christian's answer in this SO post
emgee's jsFiddle

Community
  • 1
  • 1
cssyphus
  • 37,875
  • 18
  • 96
  • 111

3 Answers3

3

This solution doesn't use a global variable, which is something to avoid if possible.

A new function parameter, counter is added. On the initial blink, counter isn't passed and will be initialized to 0 because it is undefined. With each animate function, counter is incremented by one. Everything else is your original code.

jsFiddle

function blink(selector, blink_speed, iterations, counter){
    counter = counter | 0;
    $(selector).animate({opacity:0}, 50, "linear", function(){
        $(this).delay(blink_speed);
        $(this).animate({opacity:1}, 50, function(){
            counter++;

            if (iterations == 0) {
                blink(this, blink_speed, iterations, counter);

            }else if (counter >= iterations) {
                return false;
            }else{
                blink(this, blink_speed, iterations, counter);
            }
        });
        $(this).delay(blink_speed);
    })
}
Daniel Gimenez
  • 18,530
  • 3
  • 50
  • 70
1

Your counter keeps being reset because it is defined inside the function. Moving the variable outside of the function fixed the iterations: http://jsfiddle.net/CaVEx/1/

var pad = 0;

$('#clignotant').click(function() {
    if (pad==0) {
        pad++;
        blink(this, 800, 2);
    }else{
        alert('Not document load, so now you can go to the streaming video');
    }
});
counter = 0;
function blink(selector, blink_speed, iterations){

    $(selector).animate({opacity:0}, 50, "linear", function(){
        $(this).delay(blink_speed);
        $(this).animate({opacity:1}, 50, function(){
            if (iterations == 0) {
                blink(this, blink_speed, iterations);
            }else if (counter>iterations) {
                return false;
            }else{
                counter++;
                blink(this, blink_speed, iterations);
            }
        });
        $(this).delay(blink_speed);
    });
}

//This line must come *AFTER* the $('#clignotant').click() function !!
window.load($('#clignotant').trigger('click'));
Tim Wasson
  • 3,606
  • 16
  • 16
1

You are using counter to count how much iteration you did, but there is 2 problem with this var.

The first one is that you never declare it outside the function. It get erased when the function finish and recreated when you call it.

The second is that every time you call the function, you reset the counter to 0. You should reset it just before the return false here :

else if (counter>iterations) {
    counter = 0;
    return false;
}

Here a working fiddle : http://jsfiddle.net/CaVEx/2/


Side note : Since you ar based on a 0 index, passing 15 as iteration parameter will in fact blink 16 times.

Karl-André Gagnon
  • 33,662
  • 5
  • 50
  • 75