一. 效果图
效果图
二. 需求
拖动一个shape,小圆点ball运动位置也变化。
三. 技术分析
其中运动ball是反复重复一个动作运动,不能使用transition渐变方式写,因为transition只能执行一次渐变效果,重复运动最佳的方式就是采用animation。
四. 问题
@keyframes写在css中是写死的,此时需要结束js操作@keyframes,那js是如何操作@keyframes呢,下面是我花了一天查询资料加上自己的摸索,解决了兼容IE的解决方案。
五. js操作@keyframes解决方案
- 为了方便查询以及后面循环过多产生的性能问题,一开始我们就通过js创建@keyframes
// js创建@keyframes,ball从定位在(10,10)的位置运动到(100,100) 的位置
const runkeyframes =` @keyframes ball-run{
0%{
left: 10px;
top: 10px;
}
100%{
left: 100px;
top: 100px;
}
}`
// 创建style标签
const style = document.createElement('style');
// 设置style属性
style.type = 'text/css';
// 将 keyframes样式写入style内
style.innerHTML = runkeyframes;
// 将style样式存放到head标签
document.getElementByTagName('head')[0].appendChild(style);
<style>
.ball{
width:10px;
height:10px;
border-radius:50%;
background-color:#fff
}
</style>
<!-- 这是ball的标签和样式 -->
<div id="ball" class="ball" style="animaition: ball-run 10s infinite;"></div>
- js修改@keyframes
// 获取所有的style样式
// 寻找ball keyframes对应的style样式
// 获取方式:根据animation运动的名称ball-run查询到对应的keyframes对应的style
getkeyframes=(name)=> {
var animation = {};
// 获取所有的style
var ss = document.styleSheets;
for (var i = 0; i < ss.length; ++i) {
const item = ss[i];
if (item.cssRules[0] && item.cssRules[0].name && item.cssRules[0].name === name) {
animation.cssRule = item.cssRules[0];
animation.styleSheet = ss[i];
animation.index = 0;
}
}
return animation;
}
const ballRunKeyframes = getkeyframes('ball-run');
// deleteRule方法用来从当前样式表对象中删除指定的样式规则
ballRunKeyframes.styleSheet.deleteRule(animation.index);
//重新定义ball从定位在(20,30)的位置运动到(400,500) 的位置
const runkeyframes =` @keyframes ball-run{
0%{
left: 20px;
top: 30px;
}
100%{
left: 400px;
top: 500px;
}
}`;
// insertRule方法用来给当前样式表插入新的样式规则.
ballRunKeyframes.styleSheet.insertRule(keyFrames, animation.index);
// 此时已经修改好了ball-run 对应的keyframes了,但是在坑爹的IE中小球ball依然没有改变为他的运动方式,解决方案就是,从新刷新ball Dom中的animation的值
const ball = document.getElementById('ball');
// 随便给一个animation的名称
ball.setAttribute('style','animaition: ball-run1 10s infinite;');
setTimeout(_=>{
// 1ms后纠正animation的名称
ball.setAttribute('style','animaition: ball-run 10s infinite;');
},1)
六. 总结
- 上面仅提供解决思想,建议不要复制,因为这里的代码是我在简书上手写,如有疑问咱们可以留言相互探讨。
- 注意:
1) keyframes单独写在一个style中,方便getkeyframes函数的内部遍历,想知道为什么,可以将document.styleSheets打印出来看看里面的结构就明白了。
2) js修改keyframes之后IE可能没有效果,需要重新刷新animation值 - 参考insertRule方法用来给当前样式表插入新的样式规则.,deleteRule方法用来从当前样式表对象中删除指定的样式规则两个方法
作者:zackxizi
链接:https://www.jianshu.com/p/b7b347c9783e
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。