日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 前端技术 > javascript >内容正文

javascript

JS如何监听动画结束

發布時間:2023/12/13 javascript 25 豆豆
生活随笔 收集整理的這篇文章主要介紹了 JS如何监听动画结束 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

場景描述

在使用JS控制動畫時一般需要在動畫結束后執行回調去進行DOM的相關操作,所以需要監聽動畫結束進行回調。JS提供了以下事件用于監聽動畫的結束,簡單總結學習下。

CSS3動畫監聽事件

transitionEnd事件

transitionEnd事件會在CSS transition動畫結束后觸發。

動畫結束后觸發監聽事件

<!DOCTYPE html> <html> <head><title>transtionend demo</title><style type="text/css">*{margin:0;padding: 0;}.demo{margin:100px;width:100px;height: 100px;background-color: #ddc;transition: all 0.5s ease-out;}.demo:hover{width: 200px;}</style> </head> <body><div id="demo" class="demo">鼠標移入</div><script type="text/javascript">var element = document.getElementById('demo')element.addEventListener('transitionend', handle, false)function handle(){alert('transitionend事件觸發')}</script> </body> </html>

事件多次觸發問題

當存在多個屬性過渡變化時,結束時會多次觸發transitionend事件。看個例子:
當過渡結束時,width和background-color都發生變化,會觸發兩次transionend事件

<!DOCTYPE html> <html> <head><title>transtionend demo</title><style type="text/css">*{margin:0;padding: 0;}.demo{width:100px;height: 100px;background-color: #ddc;transition: all 0.5s ease-out;}.w200{width: 200px;background-color: #fef;}</style> </head> <body><div id="demo" class="demo" onmouseover="change()" onmouseout="change()"></div><script type="text/javascript">var element = document.getElementById('demo')element.addEventListener('transitionend', handle, false)function handle(){alert('transitionend事件觸發')}function change() {element.className = element.className === 'demo' ? 'demo w200': 'demo'}</script> </body> </html>

事件失效問題及解決方案

1、在transiton動畫完成前設置display:none,事件不會觸發。

<!DOCTYPE html> <html> <head><title>transtionend demo</title><style type="text/css">*{margin:0;padding: 0;}.demo{width:100px;height: 100px;background-color: #ddc;transition: all 0.5s ease-out;}.w200{width: 200px;}</style> </head> <body><div id="demo" class="demo" onmouseover="change()" onmouseout="change()"></div><script type="text/javascript">var element = document.getElementById('demo')element.addEventListener('transitionend', handle, false)function handle(){alert('transitionend事件觸發')}function change() {element.className = element.className === 'demo' ? 'demo w200': 'demo'// 500ms后設置display:nonesetTimeout(function (){element.style.display = 'none'},400)}</script> </body> </html>

2、當transition完成前移除transition一些屬性時,事件也不會觸發,例如:

<!DOCTYPE html> <html> <head><title>transtionend demo</title><style type="text/css">*{margin:0;padding: 0;}.demo{width:100px;height: 100px;background-color: #ddc;transition: all 0.5s ease-out;}.noTranstion{width:100px;height: 100px;background-color: #ddc;}.w200{width: 200px;}</style> </head> <body><div id="demo" class="demo" onmouseover="change()" onmouseout="change()"></div><script type="text/javascript">var element = document.getElementById('demo')element.addEventListener('transitionend', handle, false)function handle(){alert('transitionend事件觸發')}function change() {element.className = element.className === 'demo' ? 'demo w200': 'demo'setTimeout(function(){element.className = 'noTranstion'},400)}</script> </body> </html>

3、元素從display:none到block,不會有過渡,導致無法觸發transitionend事件
例如:元素從display:none 到block opacity從0到1,無法觸發過渡效果。

<!DOCTYPE html> <html> <head><title>transtionend demo</title><style type="text/css">*{margin:0;padding: 0;}body{padding: 50px;}.demo{width:100px;height: 100px;background-color: #ddc;transition: all 0.5s ease-out;opacity:0;display: none;}.noTranstion{width:100px;height: 100px;background-color: #ddc;}.opt{display: block;opacity:1}.w200{width: 200px;}button{position: absolute;top: 200px;width: 100px;height: 40px;}</style> </head> <body><div id="demo" class="demo" onmouseover="change()" onmouseout="change()"></div><button onclick="change()">Click</button><script type="text/javascript">var element = document.getElementById('demo')element.addEventListener('transitionend', handle, false)function handle(){alert('transitionend事件觸發')}function change() {element.className = element.className === 'demo' ? 'demo opt': 'demo'}</script> </body> </html>

無法觸發過渡效果原因:
元素從none到block,剛生成未能即時渲染,導致過渡失效。所以需要主動觸發頁面重繪,刷新DOM。頁面重繪可以通過改變一些CSS屬性來觸發,例如:offsetTop、offsetLeft、offsetWidth、scrollTop等。
觸發過渡效果解決方案:
1、通過定時器延遲渲染

<!DOCTYPE html> <html> <head><title>transtionend demo</title><style type="text/css">*{margin:0;padding: 0;}body{padding: 50px;}.demo{width:100px;height: 100px;background-color: #ddc;transition: all 0.5s ease-out;opacity: 0;display: none;}.opt{display: block;}button{position: absolute;top: 200px;width: 100px;height: 40px;}</style> </head> <body><div id="demo" class="demo"></div><button id="button" onclick="change()">點擊</button><script type="text/javascript">var element = document.getElementById('demo')var button = document.getElementById('button')element.addEventListener('transitionend', handle, false)function handle(){alert('transitionend事件觸發')}function change() {element.className = element.className === 'demo' ? 'demo opt': 'demo'if(element.className === 'demo'){element.style.opacity = nullbutton.innerHTML = '點擊'}else{setTimeout(function(){element.style.opacity = '1'button.innerHTML = '重置'},10)}}</script> </body> </html>

2、強制獲取當前內聯樣式
通過window.getComputedStyle()方法返回應用樣式后的元的所有CSS屬性的值,并解析這些值可能包含的任何基本計算。也就是說返回的屬性值是已計算后的值,即DOM元素的樣式已經更新了。然后再改變對應屬性值觸發過渡效果。例如:

<!DOCTYPE html> <html> <head><title>transtionend demo</title><style type="text/css">*{margin:0;padding: 0;}body{padding: 50px;}.demo{width:100px;height: 100px;background-color: #ddc;transition: all 0.5s ease-out;opacity: 0;display: none;}.opt{display: block;}button{position: absolute;top: 200px;width: 100px;height: 40px;}</style> </head> <body><div id="demo" class="demo"></div><button id="button" onclick="change()">點擊</button><script type="text/javascript">var element = document.getElementById('demo')var button = document.getElementById('button')element.addEventListener('transitionend', handle, false)function handle(){alert('transitionend事件觸發')}function change() {element.className = element.className === 'demo' ? 'demo opt': 'demo'if(element.className === 'demo'){element.style.opacity = nullbutton.innerHTML = '點擊'}else{// setTimeout(function(){// element.style.opacity = '1'// button.innerHTML = '重置'// },10)window.getComputedStyle(element, null).opacityelement.style.opacity = '1'button.innerHTML = '重置'}}</script> </body> </html>

3、觸發重繪刷新DOM
通過clientWidth觸發重繪,例如:

<!DOCTYPE html> <html> <head><title>transtionend demo</title><style type="text/css">*{margin:0;padding: 0;}body{padding: 50px;}.demo{width:100px;height: 100px;background-color: #ddc;transition: all 0.5s ease-out;opacity: 0;display: none;}.opt{display: block;}button{position: absolute;top: 200px;width: 100px;height: 40px;}</style> </head> <body><div id="demo" class="demo"></div><button id="button" onclick="change()">點擊</button><script type="text/javascript">var element = document.getElementById('demo')var button = document.getElementById('button')element.addEventListener('transitionend', handle, false)function handle(){alert('transitionend事件觸發')}function change() {element.className = element.className === 'demo' ? 'demo opt': 'demo'if(element.className === 'demo'){element.style.opacity = nullbutton.innerHTML = '點擊'}else{// setTimeout(function(){// element.style.opacity = '1'// button.innerHTML = '重置'// },10)// window.getComputedStyle(element, null).opacityelement.clientWidth;element.style.opacity = '1'button.innerHTML = '重置'}}</script> </body> </html>

瀏覽器兼容性

移動端基本支持 android2.1+、webkit3.2+
詳見瀏覽器兼容性

animationEnd事件

與transitonend事件類似,詳見

Zepto中animate結束回調實現

查看了下zepto動畫模塊的源代碼,animate()方法在動畫結束后觸發回調也是通過transitionend、animationend事件來觸發。
另外在一些低版本的Android手機可能無法觸發transitionend事件,需要手動觸發。

$.fx = {off: (eventPrefix === undefined && testEl.style.transitionProperty === undefined),speeds: { _default: 400, fast: 200, slow: 600 },cssPrefix: prefix,transitionEnd: normalizeEvent('TransitionEnd'),animationEnd: normalizeEvent('AnimationEnd')} // 手動觸發事件 if (duration > 0){this.bind(endEvent, wrappedCallback)// transitionEnd is not always firing on older Android phones// so make sure it gets firedsetTimeout(function(){if (fired) returnwrappedCallback.call(that)}, ((duration + delay) * 1000) + 25)}

參考鏈接

zepto動畫模塊源碼
transitionend事件MDN
transtion屬性詳解MDN
transitionend事件詳解
Window.getComputedStyle() 方法

轉載于:https://www.cnblogs.com/GeniusLyzh/p/8324811.html

總結

以上是生活随笔為你收集整理的JS如何监听动画结束的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。