Estoy tratando de detectar cuándo termina una animación, sin embargo, los elementos secundarios activan este detector de eventos.
Entonces, si ve el código a continuación, solo la altura en el elemento con la referencia del container
debería activar el oyente, sin embargo, si verifica la consola, verá que la transición de fondo está activando esto en su lugar.
Vue.component('test', { data: function () { return { count: 0 } }, methods: { expand() { const elm = this.$refs.container; elm.addEventListener('transitionend', event => { console.log(event.target); }); elm.style.height = '100px'; } }, template: ` <div> <p @click="expand()">Expand</p> <div class="container" ref="container"> <ul> <li>Item 1</li> <li>Item 2</li> <li>Item 3</li> <li>Item 4</li> </ul> </div> </div> ` }) new Vue().$mount('#app');
.container { transition: height .3s ease; height: 0; } .container ul li:hover { background: red; } .container ul li { transition: background .2s ease-in-out; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script> <div id="app"> <test></test> </div>
animationend
bubbles , por lo que las animaciones en los elementos descendientes se propagan hasta el padre.
Si solo desea manejar el evento cuando se relaciona específicamente con elm
( this.$refs.container
), compare event.target
con elm
(o event.currentTarget
) e ignore el evento si no coinciden:
elm.addEventListener('transitionend', event => { if (event.target !== event.currentTarget) { return; // Ignore it } console.log(event.target); });
Ejemplo actualizado (agregué un borde al contenedor para que pueda ver cómo se produce la animación y ver que el console.log
sucede cuando finaliza) :
Vue.component('test', { data: function () { return { count: 0 } }, methods: { expand() { const elm = this.$refs.container; elm.addEventListener('transitionend', event => { if (event.target !== event.currentTarget) { return; // Ignore it } console.log(event.target); }); elm.style.height = '100px'; } }, template: ` <div> <p @click="expand()">Expand</p> <div class="container" ref="container"> <ul> <li>Item 1</li> <li>Item 2</li> <li>Item 3</li> <li>Item 4</li> </ul> </div> </div> ` }) new Vue().$mount('#app');
.container { transition: height .3s ease; height: 0; border: 1px solid grey; } .container ul li:hover { background: red; } .container ul li { transition: background .2s ease-in-out; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script> <div id="app"> <test></test> </div>