事件介绍
transition 相关事件有 4 个:
- transitionend: 过渡结束后触发
- transitionrun: 过渡开始后触发,不需要等待 transition-delay
- transitionstart: 过渡开始后触发,需要等完transition-delay 完成后才会触发
- transitioncancel: 当过渡被取消时触发, 后续有介绍什么时候取消
<html>
<head>
<meta charset="utf-8">
<style>
#box {
width: 100px;
height: 100px;
background: red;
transition: width 5s;
transition-delay: 1s;
}
#box:hover {
width: 400px;
}
</style>
</head>
<body>
<div id="box"></div>
<script>
var box = document.getElementById("box");
box.addEventListener("transitionend", onTransitionend);
box.addEventListener("transitionstart", onTransitionStart);
box.addEventListener('transitionrun', onTransitionrun)
box.addEventListener('transitioncancel', onTransitioncancel)
function onTransitioncancel() {
console.log('cancel')
}
function onTransitionStart() {
console.log('start');
}
function onTransitionend() {
console.log('end');
}
function onTransitionrun() {
console.log('run')
}
</script>
</body>
</html>
过渡被取消的时机
当以下情况时,过渡被取消:
- 应用于目标的 transition-property 属性的值被更改;
- display属性被设置为"none";
- 转换在运行到完成之前就停止了,例如通过将鼠标移出悬浮过渡元素;
在上面的例子中,transition-duration
为 5s, 如果鼠标停留小于 5s时,box 触发事件触发顺序为:run => start => cancel => run => start => end
,第二次 run 是因为还原的过渡。
实现简单过渡动画
<html>
<head>
<meta charset="utf-8">
<style>
div {
width: 100px;
height: 100px;
background: red;
}
.slide-enter {
width: 0;
}
.slide-enter-active {
width: 500px;
transition: width 5s;
}
.slide-enter-down {
width: 500px;
}
.slide-exit-active {
width: 0px;
transition: width 5s;
}
.slide-exit-down {
width: 0;
}
</style>
</head>
<body>
<button id="show" onclick="show()">in</button>
<button id="hide" onclick="hide()">out</button>
<script>
var box;
function show() {
box = document.createElement('div');
document.body.appendChild(box);
box.setAttribute('class', 'slide-enter')
box.ontransitionend = function () {
box.isEnd = true;
box.setAttribute('class', 'slide-enter-down')
}
setTimeout(() => {
// 一定要在一个异步任务里面, 否则没效果
// 因为这相当于初始状态有 slide-enter-active width = 500
box.setAttribute('class', 'slide-enter-active')
})
}
function hide () {
if (box.isEnd) {
box.ontransitionend = function () {
box.setAttribute('class', 'slide-exit-down')
document.body.removeChild(box);
box = null;
}
box.setAttribute('class', 'slide-exit-active')
} else {
box.ontransitionend = function () {
box.setAttribute('class', 'slide-exit-down')
document.body.removeChild(box);
box = null;
}
box.setAttribute('class', 'slide-exit-active')
}
}
</script>
</body>
</html>