事件介紹
transition 相關(guān)事件有 4 個:
- transitionend: 過渡結(jié)束后觸發(fā)
- transitionrun: 過渡開始后觸發(fā),不需要等待 transition-delay
- transitionstart: 過渡開始后觸發(fā)骑歹,需要等完transition-delay 完成后才會觸發(fā)
- transitioncancel: 當(dāng)過渡被取消時觸發(fā), 后續(xù)有介紹什么時候取消
<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>
過渡被取消的時機
當(dāng)以下情況時缤剧,過渡被取消:
- 應(yīng)用于目標(biāo)的 transition-property 屬性的值被更改溺健;
- display屬性被設(shè)置為"none";
- 轉(zhuǎn)換在運行到完成之前就停止了,例如通過將鼠標(biāo)移出懸浮過渡元素带欢;
在上面的例子中,transition-duration
為 5s, 如果鼠標(biāo)停留小于 5s時烤惊,box 觸發(fā)事件觸發(fā)順序為:run => start => cancel => run => start => end
乔煞,第二次 run 是因為還原的過渡。
實現(xiàn)簡單過渡動畫
<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(() => {
// 一定要在一個異步任務(wù)里面, 否則沒效果
// 因為這相當(dāng)于初始狀態(tài)有 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>