主页 > 采坑 > 前端采坑 > javascript常见API采坑 >
来源:未知 时间:2021-06-11 14:20 作者:小飞侠 阅读:次
[导读] 场景描述 在使用JS控制动画时一般需要在动画结束后执行回调去进行DOM的相关操作,所以需要监听动画结束进行回调。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事件。看个例子: <!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:none setTimeout(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事件 <!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> 无法触发过渡效果原因: <!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 = null button.innerHTML = '点击' }else{ setTimeout(function(){ element.style.opacity = '1' button.innerHTML = '重置' },10) } } </script> </body> </html> 2、强制获取当前内联样式 <!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 = null button.innerHTML = '点击' }else{ // setTimeout(function(){ // element.style.opacity = '1' // button.innerHTML = '重置' // },10) window.getComputedStyle(element, null).opacity element.style.opacity = '1' button.innerHTML = '重置' } } </script> </body> </html> 3、触发重绘刷新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 = null button.innerHTML = '点击' }else{ // setTimeout(function(){ // element.style.opacity = '1' // button.innerHTML = '重置' // },10) // window.getComputedStyle(element, null).opacity element.clientWidth; element.style.opacity = '1' button.innerHTML = '重置' } } </script> </body> </html> 浏览器兼容性移动端基本支持 android2.1+、webkit3.2+ animationEnd事件与transitonend事件类似,详见 https://developer.mozilla.org/zh-CN/docs/Web/API/HTMLElement/animationend_event Zepto中animate结束回调实现查看了下zepto动画模块的源代码,animate()方法在动画结束后触发回调也是通过transitionend、animationend事件来触发。 $.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 fired setTimeout(function(){ if (fired) return wrappedCallback.call(that) }, ((duration + delay) * 1000) + 25) } |
自学PHP网专注网站建设学习,PHP程序学习,平面设计学习,以及操作系统学习
京ICP备14009008号-1@版权所有www.zixuephp.com
网站声明:本站所有视频,教程都由网友上传,站长收集和分享给大家学习使用,如由牵扯版权问题请联系站长邮箱904561283@qq.com