zerkms
zerkms

Reputation: 254916

How to write blinking in more elegant way

The aim: to write a js (using jquery) that will perform 2 blinking of the row.

What I currently have is

var $second_row = $('table tr:eq(1)'),
    target_color = 'PaleGreen',
    original_color = $second_row.css('background-color');

$second_row.css('background-color', target_color);
scheduleOriginalColor();

function scheduleTargetColor() {
    setTimeout(function() {
        $second_row.css('background-color', target_color);
        scheduleOriginalColor(true);
    }, 500);
}

function scheduleOriginalColor(stop) {
    setTimeout(function() {
        $second_row.css('background-color', original_color);

        if (!stop) {
            scheduleTargetColor();
        }
    }, 500);
}
​

http://jsfiddle.net/zerkms/ecfMU/1/

But it looks ugly and I'm sure there is a better way of writing the same.

Any proposals?

UPD: there is my second attempt, a bit more clear: http://jsfiddle.net/zerkms/ecfMU/2/

var $second_row = $('table tr:eq(1)'),
    target_color = 'PaleGreen',
    original_color = $second_row.css('background-color');

setRowColor(target_color, 500);
setRowColor(original_color, 1000);
setRowColor(target_color, 1500);
setRowColor(original_color, 2000);

function setRowColor(color, timing) {
    setTimeout(function() {
        $second_row.css('background-color', color);
    }, timing);
}
​

Upvotes: 3

Views: 885

Answers (6)

Sampson
Sampson

Reputation: 268344

The following lets you define the element, color, number of flashes, and speed. Another added benefit is that it doesn't require any of the bloat of jQuery. Always favor raw JavaScript when you can.

function flashBG( e, c, x, z ) {
  var d = e.style.backgroundColor, i = 0, f = setInterval(function(){
    e.style.backgroundColor = ( e.style.backgroundColor == d ) ? c : d ;
    ++i == ( x * 2 ) && clearInterval( f );
  }, z );
}

Call it like this:

flashBG( document.body, "PaleGreen", 2, 500 );

Demo: http://jsbin.com/axuxiy/3/edit

For readability, the following may be more educational:

function flashBG( element, color, flashes, speed ) {
  var original = element.style.backgroundColor;
  var counter  = 0;
  var interval = setInterval(
    function() {
      if ( original === element.style.backgroundColor ) {
        element.style.backgroundColor = color; 
      } else {
        element.style.backgroundColor = original;
      }
      if ( ++counter == ( flashes * 2 ) ) {
        clearInterval( interval );
      }
    }, speed );
}

Upvotes: 7

CrimsonDiego
CrimsonDiego

Reputation: 3616

Javascript isn't my forte - so I may get a bit of the syntax wrong.

EDIT: Demonstration EDIT #2: Easily extensible - rainbow version

However... a very simple way of doing it is have the colors in an array, and an int var with an index. Then have only one scheduled function, like this:

//Somewhere else we have:
//var colorArray = blah... blah.. blahh, it has values [palegreen,regularwhite]

//blah blah scheduleColor(0);
//var numBlinks = 2;

//then for your scheduler
function scheduleColor(ind) {
    $second_row.css('background-color', colorArray[ind % colorArray.length]);
    if (ind < (colorArray.length * numBlinks) - 1) {
        setTimeout(function() {
            scheduleColor(ind + 1);
        }, 500);
    }
}

The basic idea is rather than two schedulers, you have one, that iterates. As a plus, you can easily set it to blink any number of times you want, or cycle through multiple colors.

Heck, if you wanted, you could have it cycle through the rainbow.

Edited for some syntax/corrections.

Upvotes: 3

Theron Luhn
Theron Luhn

Reputation: 4082

My answer for you is a portmanteau of Wesley's and Ricardo's answers, so I can't take much credit for it. I'm .delay() and .queue() along with .toggleClass(). I think it ends up a nice bit of code.

Some CSS:

.highlight {
    background-color:PaleGreen;
}

And the JS:

var $second_row = $('table tr:eq(1)');

function blink(el) {
    el.addClass('highlight');
    for(i=0; i<3; i++) {
        el.delay(500).queue(function() {
            $(this).toggleClass('highlight');
            $(this).dequeue();
        });
    }
}

blink($second_row);​

The Fiddle

Upvotes: 2

s_hewitt
s_hewitt

Reputation: 4302

Can you add jQuery UI?

If so, you can animate the background for a smoother transition.

http://jsfiddle.net/ecfMU/18/

Upvotes: 1

Ricardo Lohmann
Ricardo Lohmann

Reputation: 26320

var $second_row = $('table tr:eq(1)'),
    target_color = 'PaleGreen',
    original_color = $second_row.css('background-color');


$second_row.css('background-color', target_color).delay(500).queue(function(){
    jQuery(this).css('background-color', original_color);
});

Working : Fiddle

Upvotes: 1

No Results Found
No Results Found

Reputation: 102745

Try this, using toggleClass and a background color:

var blink = setInterval(function() {
    $('table tr:eq(1)').toggleClass('highlight');
}, 500);
setTimeout(function() {
    clearInterval(blink);
}, 2100); // run 4 times, added a little padding time just in case
.highlight {
    background-color:PaleGreen;
}

Demo: http://jsfiddle.net/ecfMU/10/

Upvotes: 7

Related Questions