以下均为个人理解,如有错误还请批评指正!
看到题主的问题,我首先联想到了zepto。它里面的animate函数也是基于css3过渡动画实现的。
zepto的fx模块源码,有一句代码很关键。
// trigger page reflow so new elements can animatethis.size() && this.get(0).clientLeft
这段代码调用元素的clientLeft以触发页面回流,使得添加的css动画得以生效。经过尝试可以发现,将相同的方法应用到题主的代码上,动画也可以正常显示。但这个过程中究竟发生了什么呢?
首先,js执行进程和浏览器渲染进程互斥(体现到这里就是DOM插入和CSS样式操作会合并计算),这可以理解为浏览器的一种优化策略。因此当js引擎执行到:
$parent.appendChild($wave);
的时候,浏览器并没有将真实的DOM元素绘制到网页上。当然,作为开发者的我们是无法观测到这一现象的。如果你使用Chrome Dev Tools断点进行观测,就会发现这两句代码被强行打成了异步执行,因此这时候的动画也是可以正常播放的!
而这时候浏览器会继续向下执行:
$wave.style.cssText = `transition: all 1s; top:${y}px; left:${x}px; opacity: 0; width:${btnWidth * 2}px; height:${btnWidth * 2}px;`;
而后js代码执行,浏览器再将已经赋予css样式的DOM元素绘制到网页上,即