TransitionEvent, AnimationEvent (1)
2022년 05월 19일
스타일을 작성할 때 단조로움을 피하기 위해서 transition과 animation 효과를 많이 쓰게 된다.
그리고 그걸 활용할 수 있는 javascript 기본 API인 TransitionEvent와 AnimationEvent에 대해 알아보려한다.
실은 이 글을 쓸때는 비교적 자주 쓰이는 이벤트 리스너의 transitionstart, transitionend, animationstart, animationend만 다룰려고 했다.
근데 이왕 글을 쓰는거 다른 이벤트 리스너들도 짤막하게 다루고 넘어가려한다.
글을 작성하다보니 길어져서 이번 글에선 transition만 다룬다.
-
new TransitionEvent('type', { propertyName: 'aPropertyName', elapsedTime: aFloat, pseudoElement: 'aPseudoElementName', });
MDN을 보면 알겠지만 실험적이라고 쓰여있다. 내가 실무에서 써본적도 없거니와 이번에 글 쓰면서 처음봤다. 새로운 TransitionEvent를 뱉는 함수인거같은데 어떻게 활용할 수 있을지는 조금 더 생각 해봐야겠다.
-
transitionrun
transition이 생성됐을 때 발동되는 이벤트 리스너이다. 난 이걸 실무에서 써본적이 없다. 거의 transitionstart로 대체해왔는데 남들은 얼마나 쓰는지 구글링을 해봐도 관련 글이 별로 없다. -
transitioncancel
transitionrun과 transitionend 사이에 transition이 취소가 되는 경우에 발생하는 이벤트 리스너인데 실무에서 꽤나 써보려 노력했지만… 내 생각대로 처리를 해주지 않아서 역시나 실무에서 써본적이 없다. -
transitionstart
transitinrun과 헷갈릴 수 있는데 transitionrun은 transition-delay를 포함한 이벤트 리스너이고 transitionstart는 실질적으로 transition action이 일어났을 때 일어난다.
난 이걸 실무에서 transitionend 다음으로 많이 쓰는 편이다. -
transitionend
transition 효과가 끝났을 때 이벤트를 주는 이벤트 리스너이다.
transition 이벤트 리스너 중에 가장 많이 쓰이는 것 같다. 구글링을 해봐도 관련 글에서 많은 차이가 난다.
그리고 transitionend를 쓰게되면 setTimeout을 써야할 곳에 유용하게 대체할 수 있다.
예를 들면 “아코디언이 열리고 나서 얼럿이 뜨게 해주세요” 라는 요청을 받을 수도 있다.
그럼 transition효과를 준 아코디언에서 저 요구 사항을 처리하려고 아래처럼 setTimeout을 쓸 수 있다.document.querySelector('아코디언 버튼').addEventListener('click', () => { setTimeout(() => { alert('이렇게 띄우는것 보단...'); }, 300); });
css에서 transition-duration을 .3s만큼 줬다고치고, setTimeout을 300만큼 주면 어찌저찌 될 수도 있지만… 생각보다 setTimeout은 정확하지 않다.
또한, 만약 transition-duration을 변경하게 되면 setTimeout의 딜레이도 수정해줘야만 한다. 그래서 아래처럼 transitionend를 활용할 수 있다.document .querySelector('열리는 아코디언 컨텐츠') .addEventListener('transitionend', () => { alert('이렇게 띄우는게 훨씬 좋을 것이다.'); });
위처럼 작성하게되면 transition-duration을 변경하여도 그에 맞춰 스크립트를 수정할 일이 없게 되고, 부정확한 setTimeout보다 훨씬 정확한 타이밍을 얻을 수 있을 것이다.
마지막으로 TransitionEvent를 쓸 때 주의할 점이 있는데 transition을 한 요소에 여러개를 넣는 경우가 있다. 예를 들어서 아래처럼 background와 width 2가지의 transition효과를 주게되면
// scss
.test {
width: 200px;
height: 200px;
background: red;
transition: all 0.3s;
&.on {
background: blue;
width: 300px;
}
}
document.querySelector('.test').addEventListener('transitionstart', function (e) {
console.log(e);
});
document.querySelector('.test').addEventListener('transitionend', function (e) {
console.log(e);
});
아래처럼 console이 각각 2개씩 찍히게된다.
// transitionstart
TransitionEvent {isTrusted: true, propertyName: 'background-color', elapsedTime: 0, pseudoElement: '', type: 'transitionstart', …}
TransitionEvent {isTrusted: true, propertyName: 'width', elapsedTime: 0, pseudoElement: '', type: 'transitionstart', …}
// transitionend
TransitionEvent {isTrusted: true, propertyName: 'background-color', elapsedTime: 0.3, pseudoElement: '', type: 'transitionend', …}
TransitionEvent {isTrusted: true, propertyName: 'width', elapsedTime: 0.3, pseudoElement: '', type: 'transitionend', …}
이러면 주고자하는 기능 역시 2번씩 실행되기 때문에
document.querySelector('.test').addEventListener('transitionstart', function (e) {
if (e.propertyName === 'width') {
console.log(e);
}
});
document.querySelector('.test').addEventListener('transitionend', function (e) {
if (e.propertyName === 'width') {
console.log(e);
}
});
위처럼 if 문으로 propertyName을 지정하여 처리하면 된다.
transition 이벤트 리스너를 써서 만든 내 개인 가이드를 보면 내가 어떤식으로 실무에서 쓰고있는지 아래 링크에서 볼 수 있다.
링크: SKY.Accordion
링크를 들어가보면 Events에서 accr.showing처럼 처음보는 이벤트 리스너를 볼 수 있게 되는데 추후에 설명할 CustomEvent와 transition 이벤트 리스너를 조합하여 커스텀 이벤트 리스너를 만든 것이다.
다음글에선 AnimationEvent에 대해서 알아보자.