CSS3转换完成后回调

C.J*_*.J. 199 javascript css jquery css3

我想淡出一个元素(将其不透明度转换为0),然后在完成时从DOM中删除元素.

在jQuery中,这是直截了当的,因为您可以在动画完成后指定"删除".但是,如果我希望使用CSS3过渡动画,那么无论如何都要知道过渡/动画何时完成?

Jim*_*ers 334

对于转换,您可以使用以下方法通过jQuery检测转换的结束:

$("#someSelector").bind("transitionend webkitTransitionEnd oTransitionEnd MSTransitionEnd", function(){ ... });
Run Code Online (Sandbox Code Playgroud)

Mozilla有一个很好的参考:

https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Transitions/Using_CSS_transitions#Detecting_the_start_and_completion_of_a_transition

对于动画,它非常相似:

$("#someSelector").bind("animationend webkitAnimationEnd oAnimationEnd MSAnimationEnd", function(){ ... });
Run Code Online (Sandbox Code Playgroud)

请注意,您可以同时将所有浏览器前缀事件字符串传递到bind()方法,以支持在支持它的所有浏览器上触发事件.

更新:

根据Duck留下的评论:你使用jQuery的.one()方法来确保处理程序只触发一次.例如:

$("#someSelector").one("transitionend webkitTransitionEnd oTransitionEnd MSTransitionEnd", function(){ ... });

$("#someSelector").one("animationend webkitAnimationEnd oAnimationEnd MSAnimationEnd", function(){ ... });
Run Code Online (Sandbox Code Playgroud)

更新2:

jQuery bind()方法已被弃用,并且on()方法是首选的jQuery 1.7.bind()

您还可以off()在回调函数上使用方法,以确保它只会被触发一次.这是一个相当于使用one()方法的例子:

$("#someSelector")
.on("animationend webkitAnimationEnd oAnimationEnd MSAnimationEnd",
 function(e){
    // do something here
    $(this).off(e);
 });
Run Code Online (Sandbox Code Playgroud)

参考文献:

  • @Lev您可以通过将事件的currentTarget与其目标进行比较来轻松缓解此问题.所以类似于:function(event){if(event.target === event.currentTarget){/*Do stuff*/}} (22认同)
  • 值得注意的是,回调将针对*每个*子元素也会被触发.这一点非常重要,因为如果您想知道为什么您的回调被触发的次数比您预期的要多.到目前为止,我还没有意识到任何解决方法. (13认同)
  • 对于jQuery v1.7 + http://api.jquery.com/bind/,我们使用`.on()`而不是`.bind()` (9认同)
  • 是的,我在撰写评论后不久就想到了这一点.> _ <感谢您发布; 我相信它会帮助别人!:) (5认同)
  • 所有现代浏览器现在都支持未加前缀的事件.http://caniuse.com/#feat=css-transitions另请注意,如果您有"transitionend webkitTransitionEnd",它将在Chrome中触发两次. (4认同)
  • @JimJeffers你可以使用"早回家"模式,通过做,if(event.target!= event.currentTarget)返回; (3认同)
  • 使用`.one()`而不是`.on()`或`.bind()`.这将确保它只能运行一次,然后它将从事件处理程序解除绑定. (2认同)

ROF*_*IME 17

另一个选择是使用jQuery Transit Framework来处理你的CSS3过渡.转换/效果在移动设备上表现良好,您不必在CSS文件中添加一行杂乱的CSS3过渡以执行动画效果.

下面是一个示例,当您单击它时将元素的不透明度转换为0,并在转换完成后将其删除:

$("#element").click( function () {
    $('#element').transition({ opacity: 0 }, function () { $(this).remove(); });
});
Run Code Online (Sandbox Code Playgroud)

JS小提琴演示


Yeh*_*rtz 8

有一个animationend可以观察到的事件,请参见此处的文档,对于css transition动画,也可以使用该transitionend事件

document.getElementById("myDIV").addEventListener("transitionend", myEndFunction);
function myEndFunction() {
	this.innerHTML = "transition event ended";
}
Run Code Online (Sandbox Code Playgroud)
#myDIV {transition: top 2s; position: relative; top: 0;}
div {background: #ede;cursor: pointer;padding: 20px;}
Run Code Online (Sandbox Code Playgroud)
<div id="myDIV" onclick="this.style.top = '55px';">Click me to start animation.</div>
Run Code Online (Sandbox Code Playgroud)

  • 这是一个界限[仅链接的答案](// meta.stackexchange.com/q/8231)。您应该扩展答案以在此处包含尽可能多的信息,并且仅将链接用作参考。 (2认同)
  • 投票支持它,因为它是不依赖jQuery的第一个。砍掉整棵树作为分支没有意义。 (2认同)
  • 现在浏览器更加步调一致——例如,不需要前缀——这种普通的 Javascript 解决方案可能是当今(2020 年)公认的答案。赞成不依赖 jQuery 来回答一个相对简单的问题。 (2认同)

Dav*_*air 7

对于这个可能很方便的人来说,这里有一个jQuery依赖函数,我成功地通过CSS类应用CSS动画,然后从后面获得回调.它可能无法正常工作,因为我在Backbone.js应用程序中使用它,但可能有用.

var cssAnimate = function(cssClass, callback) {
    var self = this;

    // Checks if correct animation has ended
    var setAnimationListener = function() {
        self.one(
            "webkitAnimationEnd oanimationend msAnimationEnd animationend",
            function(e) {
                if(
                    e.originalEvent.animationName == cssClass &&
                    e.target === e.currentTarget
                ) {
                    callback();
                } else {
                    setAnimationListener();
                }
            }
        );
    }

    self.addClass(cssClass);
    setAnimationListener();
}
Run Code Online (Sandbox Code Playgroud)

我用它有点像这样

cssAnimate.call($("#something"), "fadeIn", function() {
    console.log("Animation is complete");
    // Remove animation class name?
});
Run Code Online (Sandbox Code Playgroud)

最初的想法来自http://mikefowler.me/2013/11/18/page-transitions-in-backbone/

这看起来很方便:http://api.jqueryui.com/addClass/


更新

在努力学习上述代码和其他选项之后,我建议对任何侦听CSS动画结束都非常谨慎.随着多个动画的继续,这对于事件收听来说会非常快.我强烈建议像GSAP这样的动画库用于每个动画,甚至是小动画.


Chu*_*utt 5

目前,对于Chrome中的动画,已接受的答案会触发两次。大概是因为它识别webkitAnimationEndanimationEnd。以下内容肯定只会触发一次:

/* From Modernizr */
function whichTransitionEvent(){

    var el = document.createElement('fakeelement');
    var transitions = {
        'animation':'animationend',
        'OAnimation':'oAnimationEnd',
        'MSAnimation':'MSAnimationEnd',
        'WebkitAnimation':'webkitAnimationEnd'
    };

    for(var t in transitions){
        if( transitions.hasOwnProperty(t) && el.style[t] !== undefined ){
            return transitions[t];
        }
    }
}

$("#elementToListenTo")
    .on(whichTransitionEvent(),
        function(e){
            console.log('Transition complete!  This is the callback!');
            $(this).off(e);
        });
Run Code Online (Sandbox Code Playgroud)

  • 我建议改为调用函数whichAnimationEvent(),因为它处理动画事件。 (3认同)