简体   繁体   中英

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);
}
​

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/

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 );
}

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.

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

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

Can you add jQuery UI?

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

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM