用JavaScript编写相同深度回调的更好方法

用JavaScript编写相同深度回调的更好方法,javascript,callback,Javascript,Callback,我正在编写一段代码,它使用一个函数(来自RaphaelJS)使HTML元素闪烁三次,该函数的签名类似于animate(params、delay、easing、callback)。其思想是当动画完成时,callback在delay毫秒后执行。因此,我有以下代码: var theElement = anElement; function animateOpacity(newOpacity, callback) { theElement.animate({ opacity: newOpaci

我正在编写一段代码,它使用一个函数(来自RaphaelJS)使HTML元素闪烁三次,该函数的签名类似于
animate(params、delay、easing、callback)
。其思想是当动画完成时,
callback
delay
毫秒后执行。因此,我有以下代码:

var theElement = anElement;

function animateOpacity(newOpacity, callback) {
    theElement.animate({ opacity: newOpacity }, 500, null, callback);
}

function blink() {
    animateOpacity(0.1, function() {
        animateOpacity(1, function() {
            animateOpacity(0.1, function() {
                animateOpacity(1, function() {
                    animateOpacity(0.1, function() {
                        theElement.remove();
                    });
                });
             });
         });
     });
  }

…看起来很可怕。有人知道有没有更好的方法可以将这个
animateocapity
函数作为回调调用,而不使用所有这些嵌套的匿名函数?谢谢。

您可以使用通用代码和计数器:

function blink(theElement, numBlinks) {

    var lastOpacity = 0.1;

    function animateOpacity(newOpacity, callback) {
        theElement.animate({ opacity: newOpacity }, 500, null, callback);
    }

    function next() {
        --numBlinks;
        if (numBlinks > 0) {
            lastOpacity = lastOpacity < 1 ? 1: 0.1;
            animateOpacity(lastOpacity, next);
        } else {
            theElement.remove();
        }
    }

    animateOpacity(0.1, next);

}
功能闪烁(元素、链接){
var lastOpacity=0.1;
函数animatePocity(newOpacity,回调){
动画({opacity:newOpacity},500,null,回调);
}
函数next(){
--麻木链接;
如果(链接数>0){
lastOpacity=lastOpacity<1?1:0.1;
animateOpacity(lastOpacity,next);
}否则{
theElement.remove();
}
}
animateOpacity(0.1,下一个);
}

您可以使用通用代码和计数器:

function blink(theElement, numBlinks) {

    var lastOpacity = 0.1;

    function animateOpacity(newOpacity, callback) {
        theElement.animate({ opacity: newOpacity }, 500, null, callback);
    }

    function next() {
        --numBlinks;
        if (numBlinks > 0) {
            lastOpacity = lastOpacity < 1 ? 1: 0.1;
            animateOpacity(lastOpacity, next);
        } else {
            theElement.remove();
        }
    }

    animateOpacity(0.1, next);

}
功能闪烁(元素、链接){
var lastOpacity=0.1;
函数animatePocity(newOpacity,回调){
动画({opacity:newOpacity},500,null,回调);
}
函数next(){
--麻木链接;
如果(链接数>0){
lastOpacity=lastOpacity<1?1:0.1;
animateOpacity(lastOpacity,next);
}否则{
theElement.remove();
}
}
animateOpacity(0.1,下一个);
}

我这样更改了您的代码(这就是我所说的回调循环):


我这样更改了您的代码(我称之为回调循环):

但也有一些库提供了这种功能

当然,您也可以这样做(未经测试):

功能闪烁(不透明度、计数){
不透明度=不透明度===.1?1:.1;
如果(计数<3){
animatePocity(不透明度,blink.bind(null,不透明度,++count));
}
}
眨眼(1,0);
签出(.但是也有一些库提供了这种功能

当然,您也可以这样做(未经测试):

功能闪烁(不透明度、计数){
不透明度=不透明度===.1?1:.1;
如果(计数<3){
animatePocity(不透明度,blink.bind(null,不透明度,++count));
}
}
眨眼(1,0);
您可以使用setInterval()或setTimeout()函数

更干净的方式

使用条件检查三次

您可以使用setInterval()或setTimeout()函数

更干净的方式


使用一个条件来检查三次

我会将其分解为几个称为conditionally的回调:

var theElement = anElement,
    blinksRemaining = 3;

function animateOpacity(newOpacity, callback) {
    theElement.animate({ opacity: newOpacity }, 500, null, callback);
}
function removeElement() {
    theElement.remove();
}

function fadeOutThenIn() {
    blinksRemaining--;
    animateOpacity(0.1, blink);
}

function blink() {
    animateOpacity(1, blinksRemaining ? fadeOutThenIn : removeElement);
}

blink();

我会将其分解为几个回调,称为Conditionally:

var theElement = anElement,
    blinksRemaining = 3;

function animateOpacity(newOpacity, callback) {
    theElement.animate({ opacity: newOpacity }, 500, null, callback);
}
function removeElement() {
    theElement.remove();
}

function fadeOutThenIn() {
    blinksRemaining--;
    animateOpacity(0.1, blink);
}

function blink() {
    animateOpacity(1, blinksRemaining ? fadeOutThenIn : removeElement);
}

blink();

未经测试,但我认为以下方法应该有效:

var theElement = anElement;

function animateOpacity(newOpacity, callback) {
    theElement.animate({ opacity: newOpacity }, 500, null, callback);
}

function blink() {
    var args = [0.1, 1, 0.1, 1, 0.1];
    var func = function() {
        theElement.remove();
    };
    for (var i = args.length - 1; i >= 0; i--) {
        func = animateOpacity.bind(null, args[i], func);
    }
    func();
}

这里的想法是从内部到外部创建函数,将内部函数作为一个参数绑定到新的外部函数以及每个步骤的另一个参数。

未经测试,但我认为以下方法应该有效:

var theElement = anElement;

function animateOpacity(newOpacity, callback) {
    theElement.animate({ opacity: newOpacity }, 500, null, callback);
}

function blink() {
    var args = [0.1, 1, 0.1, 1, 0.1];
    var func = function() {
        theElement.remove();
    };
    for (var i = args.length - 1; i >= 0; i--) {
        func = animateOpacity.bind(null, args[i], func);
    }
    func();
}

这里的想法是从内部到外部创建函数,将内部函数作为参数绑定到新的外部函数以及每个步骤的其他参数。

一种可能性是使用具有间隔的conttolling函数

function blinkingBlinker(newOpacity, callback){
    var blink_count = 0;
    var blink = setInterval(animateOpacity,1000);

    function animateOpacity(){
        blink_count++;

       function animateOpacity() {
          theElement.animate({ opacity: newOpacity }, 500, null, callback);
          }

        if (blink_count==3){
            clearInterval(blink)
        }
    }}

因此,您调用blinkingBlinker函数,它会在内部每秒运行AnimateCapity,直到闪烁计数超过您想要的闪烁次数。

一种可能是使用具有间隔的旋转功能

function blinkingBlinker(newOpacity, callback){
    var blink_count = 0;
    var blink = setInterval(animateOpacity,1000);

    function animateOpacity(){
        blink_count++;

       function animateOpacity() {
          theElement.animate({ opacity: newOpacity }, 500, null, callback);
          }

        if (blink_count==3){
            clearInterval(blink)
        }
    }}

因此,您可以调用blinkingBlinker函数,它会在内部每秒运行AnimateCapity,直到闪烁次数超过您想要的闪烁次数。

可以使用以下css模拟闪烁效果

    @-webkit-keyframes blinker { from {opacity:1.0;} to {opacity:0.1;} }
    @keyframes blinker { from {opacity:1.0;} to {opacity:0.1;} }
    #element{

        text-decoration:blink;
        -webkit-animation-name:blinker;
        animation-name:blinker;
        -webkit-animation-iteration-count:10;
        animation-iteration-count:10;
        -webkit-animation-timing-function:cubic-bezier(1.0,0,0,1.0);
        animation-timing-function:cubic-bezier(1.0,0,0,1.0);
        -webkit-animation-duration:0.5s;
        animation-duration:0.5s; 
     }

可以使用以下css模拟闪烁效果

    @-webkit-keyframes blinker { from {opacity:1.0;} to {opacity:0.1;} }
    @keyframes blinker { from {opacity:1.0;} to {opacity:0.1;} }
    #element{

        text-decoration:blink;
        -webkit-animation-name:blinker;
        animation-name:blinker;
        -webkit-animation-iteration-count:10;
        animation-iteration-count:10;
        -webkit-animation-timing-function:cubic-bezier(1.0,0,0,1.0);
        animation-timing-function:cubic-bezier(1.0,0,0,1.0);
        -webkit-animation-duration:0.5s;
        animation-duration:0.5s; 
     }