Skip to content

Commit 635d6c9

Browse files
committed
Handle immediate leave transition after enter (fix #1116)
If a CSS transition leaves immediately after enter, the transitionend event never fires because the CSS values didn't have time to interpolate. This can cause items to leave hanging in the DOM or cause out-in mode to never append the entering item. By detecting that we just entered last tick we can end a leave transition immediately.
1 parent 68d37ff commit 635d6c9

File tree

1 file changed

+17
-2
lines changed

1 file changed

+17
-2
lines changed

src/transition/transition.js

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ var animDurationProp = _.animationProp + 'Duration'
1010
var TYPE_TRANSITION = 1
1111
var TYPE_ANIMATION = 2
1212

13+
var uid = 0
14+
1315
/**
1416
* A Transition object that encapsulates the state and logic
1517
* of the transition.
@@ -21,6 +23,7 @@ var TYPE_ANIMATION = 2
2123
*/
2224

2325
function Transition (el, id, hooks, vm) {
26+
this.id = uid++
2427
this.el = el
2528
this.enterClass = id + '-enter'
2629
this.leaveClass = id + '-leave'
@@ -33,6 +36,7 @@ function Transition (el, id, hooks, vm) {
3336
this.pendingJsCb =
3437
this.op =
3538
this.cb = null
39+
this.justEntered = false
3640
this.typeCache = {}
3741
// bind
3842
var self = this
@@ -87,6 +91,10 @@ p.enter = function (op, cb) {
8791
*/
8892

8993
p.enterNextTick = function () {
94+
this.justEntered = true
95+
_.nextTick(function () {
96+
this.justEntered = false
97+
}, this)
9098
var type = this.getCssTransitionType(this.enterClass)
9199
var enterDone = this.enterDone
92100
if (type === TYPE_TRANSITION) {
@@ -140,10 +148,17 @@ p.leave = function (op, cb) {
140148
addClass(this.el, this.leaveClass)
141149
this.callHookWithCb('leave')
142150
this.cancel = this.hooks && this.hooks.leaveCancelled
143-
// only need to do leaveNextTick if there's no explicit
151+
// only need to handle leaveDone if there's no explicit
144152
// js callback
145153
if (!this.pendingJsCb) {
146-
queue.push(this.leaveNextTick)
154+
// if a CSS transition leaves immediately after enter,
155+
// the transitionend event never fires. therefore we
156+
// detect such cases and end the leave immediately.
157+
if (this.justEntered) {
158+
this.leaveDone()
159+
} else {
160+
queue.push(this.leaveNextTick)
161+
}
147162
}
148163
}
149164

0 commit comments

Comments
 (0)