Javascript使用三大家族和事件来DIY动画效果相关笔记(六)
1.图片轮播之旋转木马
◆原理:将每张图片的样式都存到一个数组中,每一张图片的样式有多个,所以那个数组里面的元素都是对象,通过制作的缓速框架,移动每一张图片对象,缓速改变图片的样式,缓速改变的样式都在数组元素的对象里,所以改变了数组中元素的位置,就让图片轮播起来,并且还是以旋转木马的方式,通过将第一个元素shift然后push达到顺时针旋转,通过将最后一个元素pop然后unshift达到逆时针旋转。防止狂点的方法是,定义一个标识,一开始这个表示为true,当点击一下之后,把这个标识赋值为false,等整个动画都执行完毕之后,在赋值为true,这样就能防止动画没有结束完毕右执行了下一个动画。
◆技巧:先定义一个数组,数组中的元素是json;json中的元素是属性。点击一个按钮,按顺序更换数组中元素的位置。(如果想完成旋转木马,只需要更换数组中元素的位置)
◆步骤:
◇.必须让页面加载的时候把所有的属性加载出来
◇鼠标放到大盒子上显示对应的左右切换按钮,移开隐藏
◇获取两个按钮。对他们进行事件绑定。对他们进行判断。
◇如果是左侧的按钮执行一套程序,如果是右侧的按钮执行另一套程序。
◇绑定按钮的函数,一个是正转,一个是反转。(传参确定)
◇调换相应的数组对应的元素。(先删除谁,在怎么添加)
◆正方向轮播与反方向轮播:
◇最开始是:12345;我想让他变成:23451
◇把1删除,在最后添加1;
◇在数组json中,删除第一个元素,添加到最末尾。(正转)
◇在数组json中,删除最后一个元素,添加到第一位。(反转)
◆函数节流:定义一个变量,只有函数执行完毕在去执行下一个。
★轮播动画旋转木马
☆index.js
/**
* 功能:获取兼容borderRadius的getStyle框架
* @param elemnet
* @param attribute
* @returns {string}
*/
function getStyle(elemnet, attribute) {
// 左边||右边
// 左边在有些主流浏览器上获取不到内嵌式和外链式以及行内式的border-radius
// 右边只能够获取到行内式的border-radius
// 所以无论是左边还是右边,在某些浏览器上 肯定获取不到内嵌式和外链式的 border-radius
// 当左边和右边都获取不到时,返回值都是""空字符串,于是就判断一下 是否是border-radius
var sty = (elemnet.currentStyle
?
elemnet.currentStyle[attribute]
:
window.getComputedStyle(elemnet, null)[attribute]
) || elemnet.style[attribute];
//判断获取到的值是否为空字符串
if ("" == sty) {
switch (attribute) {
case "borderRadius":
case "border-radius":
(sty = elemnet.currentStyle
?
elemnet.currentStyle["border-top-left-radius"]
:
window.getComputedStyle(elemnet, null)["border-top-left-radius"]);
break;
default:
sty;
break;
}
}
return sty;
}
//3.封装animate缓速框架
/**
* 功能:缓速改变元素的样式属性值 达到缓速动画的效果
* @param element
* @param styleJson
* @param fn
*/
function animate(element, styleJson, fn) {
//使用定时器之前必须先清除定时器
clearInterval(element.timer);
//开始使用定时器
element.timer = setInterval(function () {
//开闭思想 当每一个样式对象的成员都达到目标时
element.bool = true;
//遍历需要变化的每一个样式对象成员
for (var key in styleJson) {
//key 就是要变化的样式属性名
//styleJson[key] 就是要变化的样式的属性的目标值
//首先防止 突发情况的发生
//例如:按住ctrl键然后鼠标滑轮滚动
// 导致getStyle获取到的值本来没有小数,
// 变得带有小数了,解决这个问题的方法是
// 先替换掉px,然后再向上取整即可,
// 就算你本来的值是有小数的,
// 但是向上取整在整个动画中的改变也是没什么的。
// 如果使用parseInt会导致getStyle获取到的值为0.9时
// 变成0,所以不用parseInt向下取整。
// element.leader = Math.ceil(getStyle(element, key).replace("px", "") / 1) || 0;
//如果值为透明度时
if (key == "opacity") {
element.leader = 100 * (getStyle(element, key).replace("px", "") / 1 || 1);
} else {
element.leader = Math.ceil(getStyle(element, key).replace("px", "") / 1) || 0;
}
//缓速步长的第一次获取
element.speed = (styleJson[key] - element.leader) / 10;
//缓速步长的第二次计算
element.speed = element.speed > 0 ? Math.ceil(element.speed) : Math.floor(element.speed);
//匀速步长的计算
//element.speed = styleJson[key] > element.leader ? 10 : -10;
//只剩一步之遥时
if (Math.abs(styleJson[key] - element.leader) <= Math.abs(element.speed)) {
//如果值为透明度时
if (key == "opacity") {
element.style[key] = styleJson[key] / 100;
element.style["fliter"] = "alpha(opacity=" + styleJson[key] + ")";
continue;
} else if (key == "z-index" || key == "zIndex") {//如果为层级时
element.style[key] = styleJson[key];
continue;
}
element.style[key] = styleJson[key] + "px";
continue;
} else {
//只要有一个样式对象的成员没有达到目标
// 这个清除定时器的bool值就为false
element.bool = false;
}
//如果值为透明度时
if (key == "opacity") {
element.style[key] = (element.leader + element.speed) / 100;
element.style["fliter"] = "alpha(opacity=" + (element.leader + element.speed) + ")";
continue;
} else if (key == "z-index" || key == "zIndex") { //如果为层级时
element.style[key] = element.leader + element.speed;
continue;
}
//开始移动
element.style[key] = element.leader + element.speed + "px";
}
console.log(1);//测试定时器有没有停下来
//是否都达到要求了
if (element.bool) {
clearInterval(element.timer);
//回调函数是否存在
if (fn) {
//执行回调函数
fn();
}
}
}, 18);
}
☆json.js
var arr = [
{ // 1
width:350,
top:50,
left:225,
opacity:10,
z:1
},
{ // 1
width:400,
top:70,
left:50,
opacity:20,
z:2
},
{ // 2
width:600,
top:120,
left:0,
opacity:80,
z:3
},
{ // 3
width:800,
top:100,
left:200,
opacity:100,
z:4
},
{ // 4
width:600,
top:120,
left:600,
opacity:80,
z:3
},
{ //5
width:400,
top:70,
left:750,
opacity:20,
z:2
}
,
{ //5
width:350,
top:50,
left:625,
opacity:10,
z:1
}
];
☆html:轮播图片大小800*500
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>轮播动画旋转木马</title>
<style type="text/css">
/*初始化 reset*/
/*blockquote,body,button,dd,dl,dt,fieldset,form,h1,h2,h3,h4,h5,h6,hr,input,legend,li,ol,p,pre,td,textarea,th,ul{margin:0;padding:0}*/
body, li, ul {
margin: 0;
padding: 0
}
ol, ul {
list-style: none
}
a {
text-decoration: none
}
fieldset, img {
border: 0;
vertical-align: top;
}
a, input, button, select, textarea {
outline: none;
}
a, button {
cursor: pointer;
}
.wrap {
width: 1200px;
margin: 10px auto;
}
.slide {
height: 500px;
position: relative;
}
.slide li {
position: absolute;
left: 200px;
top: 0;
}
.slide li img {
width: 100%;
}
.arrow {
/*opacity: 0;*/
}
.prev, .next {
width: 76px;
height: 112px;
position: absolute;
top: 50%;
margin-top: -56px;
background: url(data:image/png;base64,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) no-repeat;
z-index: 99;
}
.next {
right: 0;
background-image: url(data:image/png;base64,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);
}
</style>
</head>
<body>
<div class="wrap" id="wrap">
<div class="slide" id="slide">
<ul>
<!--五张图片-->
<li><a href="#"><img src="images/slidepic1.jpg" alt=""/></a></li>
<li><a href="#"><img src="images/slidepic2.jpg" alt=""/></a></li>
<li><a href="#"><img src="images/slidepic3.jpg" alt=""/></a></li>
<li><a href="#"><img src="images/slidepic4.jpg" alt=""/></a></li>
<li><a href="#"><img src="images/slidepic5.jpg" alt=""/></a></li>
<li><a href="#"><img src="images/slidepic6.jpg" alt=""/></a></li>
<li><a href="#"><img src="images/slidepic7.jpg" alt=""/></a></li>
<!--<li><a href="#"><img src="images/slidepic8.jpg" alt=""/></a></li>-->
<!--<li><a href="#"><img src="images/slidepic9.jpg" alt=""/></a></li>-->
</ul>
<!--左右切换按钮-->
<div class="arrow" id="arrow">
<a href="javascript:;" class="prev"></a>
<a href="javascript:;" class="next"></a>
</div>
</div>
</div>
<script src="js/index.js"></script>
<script src="js/json.js"></script>
<script>
//需求:加载的时候以一种旋转木马的样式展示
// 点击向左的箭头时 把右边的图片切换到中间(其实就是修改成为最显眼的样式)
// 点击向右的箭头时 把左边的图片切换到中间(其实就是修改成为最显眼的样式)
//思路:当点击向左的箭头时,顺时针旋转,将数组最后一个元素插入到数组的最前面
// 点击向右的箭头时,逆时针旋转,将数组的第一个元素插入到数组的最后面
//步骤:
//1.获取事件源及相关对象
//2.绑定事件
//3.书写事件驱动程序
//1.获取事件源及相关对象
var slide = document.getElementById("slide");
var ul = slide.children[0];
var arrow = document.getElementById("arrow");
//2.绑定事件
move();
var flag = true;//防止动画没有执行完就进入下一个动画
for (var i = 0; i < arrow.children.length; i++) {
arrow.children[i].onclick = function () {
if (flag) {
if (i) {
flag = false;
move(false);
} else {
flag = false;
move(true);
}
}
}
}
//初始化 旋转木马
//3.书写事件驱动程序
/**
* 旋转木马移动的动画
*/
function move(bool) {
if (bool === true || false === bool) {
if (bool) {
//点击向右的箭头时,逆时针旋转,将数组的第一个元素插入到数组的最后面
var item = arr.shift();
arr.push(item);
} else {
//当点击向左的箭头时,顺时针旋转,将数组最后一个元素插入到数组的最前面
//从数组最后面添加元素push
//从数组最后面取出元素pop
//从数组最前面插入元素unshift
//从元素最前面去除元素shift
var item = arr.pop();
arr.unshift(item);
}
}
for (var i = 0; i < ul.children.length; i++) {
animate(ul.children[i], {
width: arr[i].width,
top: arr[i].top,
left: arr[i].left,
opacity: arr[i].opacity,
zIndex: arr[i].z
}, function () {
//动画执行完毕后才能继续执行下一次动画
flag = true;
// for (var j = 0; j < ul.children.length; j++) {
// //设置图片的圆角边框
//// animate(ul.children[j].children[0].children[0], {borderRadius: 1}, null);
// }
});
}
}
</script>
</body>
</html>
2.有些样式的属性值,在某些浏览器上是无法直接获取的,原来的内嵌式与外链式的获取方式还有行内式的获取方式也是无法直接获取的,只能够通过获取获取其子样式属性来获取,于是以下是getStyle新版本的封装,兼容border-radius的获取
/**
* 功能:获取兼容borderRadius的getStyle框架
* @param elemnet
* @param attribute
* @returns {string}
*/
function getStyle(elemnet, attribute) {
// 左边||右边
// 左边在有些主流浏览器上获取不到内嵌式和外链式以及行内式的border-radius
// 右边只能够获取到行内式的border-radius
// 所以无论是左边还是右边,在某些浏览器上 肯定获取不到内嵌式和外链式的 border-radius
// 当左边和右边都获取不到时,返回值都是""空字符串,于是就判断一下 是否是border-radius
var sty = (elemnet.currentStyle
?
elemnet.currentStyle[attribute]
:
window.getComputedStyle(elemnet, null)[attribute]
) || elemnet.style[attribute];
//判断获取到的值是否为空字符串
if ("" == sty) {
switch (attribute) {
case "borderRadius":
case "border-radius":
(sty = elemnet.currentStyle
?
elemnet.currentStyle["border-top-left-radius"]
:
window.getComputedStyle(elemnet, null)["border-top-left-radius"]);
break;
default:
sty;
break;
}
}
return sty;
}
3.改进改进兼容性缓速框架
◆改进兼容性缓速框架(高级版)-圆边框样式
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>改进兼容性缓速框架(高级版)-圆边框样式</title>
<style type="text/css">
.box {
height: 200px;
background-color: #eee;
position: relative;
padding-left: 100px;
padding-top: 20px;
}
#box1 {
width: 80px;
height: 80px;
background-color: #701;
position: absolute;
top: 60px;
left: 100px;
/*box-shadow: #a01 0px 0px 80px 10px;*/
border-radius: 1px;
}
</style>
</head>
<body>
<div class="box">
<button>变成圆球向右滚,滚完之后再回来,恢复原样</button>
<div id="box1"></div>
</div>
<script>
//需求:
// 点击按钮之后,
// 小方块儿向右缓速滚动,
// 边滚动边变成小圆球,
// 滚到指定位置后,
// 再缓速滚回来,
// 边滚边恢复原样
//思路:
// 在有些主流浏览器上,
// 直接获取border-radius的内嵌样式与外链样式的属性值,
// 所以需要重新封装一个getStyle方法,
// 从而能够获取到border-radius,
// 然后重新封装一遍缓速动画的框架,
// 传递的参数:
// 1.需要缓速改变样式的元素对象、
// 2.已经样式参数集合对象(样式json)
// 3.回调函数,当缓速动画结束之后再执行的方法
//步骤:
//1.老三步
//2.封装getStyle兼容border-radius的框架
//3.封装animate缓速框架
//1.老三步
//1.1获取事件源及相关元素对象
var box = document.getElementsByTagName("div")[0];
var btn = box.children[0];
var box1 = box.children[1];
//1.2绑定事件源
btn.onclick = function () {
//1.3书写事件驱动程序
// animate(box1,{width:150,height:120,left:400,top:180,"border-radius":50})
animate(box1, {left: 1000, "borderRadius": 50}, function () {
animate(box1, {left: 100, "borderRadius": 1}, null);
});
// animate(box1, {left: 1000, "border-radius": 50}, function () {
// animate(box1, {top: 500, "border-radius": 1}, function () {
// animate(box1, {left: 100, "border-radius": 50}, function () {
// animate(box1, {top: 60, "border-radius": 1}, null);
// });
// });
// });
}
//2.封装getStyle兼容border-radius的框架
/**
* 功能:获取兼容borderRadius的getStyle框架
* @param elemnet
* @param attribute
* @returns {string}
*/
function getStyle(elemnet, attribute) {
// 左边||右边
// 左边在有些主流浏览器上获取不到内嵌式和外链式以及行内式的border-radius
// 右边只能够获取到行内式的border-radius
// 所以无论是左边还是右边,在某些浏览器上 肯定获取不到内嵌式和外链式的 border-radius
// 当左边和右边都获取不到时,返回值都是""空字符串,于是就判断一下 是否是border-radius
var sty = (elemnet.currentStyle
?
elemnet.currentStyle[attribute]
:
window.getComputedStyle(elemnet, null)[attribute]
) || elemnet.style[attribute];
//判断获取到的值是否为空字符串
if ("" == sty) {
switch (attribute) {
case "borderRadius":
case "border-radius":
(sty = elemnet.currentStyle
?
elemnet.currentStyle["border-top-left-radius"]
:
window.getComputedStyle(elemnet, null)["border-top-left-radius"]);
break;
default:
sty;
break;
}
}
return sty;
}
//3.封装animate缓速框架
/**
* 功能:缓速改变元素的样式属性值 达到缓速动画的效果
* @param element
* @param styleJson
* @param fn
*/
function animate(element, styleJson, fn) {
//使用定时器之前必须先清除定时器
clearInterval(element.timer);
//开始使用定时器
element.timer = setInterval(function () {
//开闭思想 当每一个样式对象的成员都达到目标时
element.bool = true;
//遍历需要变化的每一个样式对象成员
for (var key in styleJson) {
//key 就是要变化的样式属性名
//styleJson[key] 就是要变化的样式的属性的目标值
//首先防止 突发情况的发生
//例如:按住ctrl键然后鼠标滑轮滚动
// 导致getStyle获取到的值本来没有小数,
// 变得带有小数了,解决这个问题的方法是
// 先替换掉px,然后再向上取整即可,
// 就算你本来的值是有小数的,
// 但是向上取整在整个动画中的改变也是没什么的。
// 如果使用parseInt会导致getStyle获取到的值为0.9时
// 变成0,所以不用parseInt向下取整。
element.leader = Math.ceil(getStyle(element, key).replace("px", "") / 1) || 0;
//缓速步长的第一次获取
element.speed = (styleJson[key] - element.leader) / 10;
//缓速步长的第二次计算
element.speed = element.speed > 0 ? Math.ceil(element.speed) : Math.floor(element.speed);
//只剩一步之遥时
if (Math.abs(styleJson[key] - element.leader) <= Math.abs(element.speed)) {
element.style[key] = styleJson[key] + "px";
continue;
} else {
//只要有一个样式对象的成员没有达到目标
// 这个清除定时器的bool值就为false
element.bool = false;
}
//开始移动
element.style[key] = element.leader + element.speed + "px";
}
console.log(1);//测试定时器有没有停下来
//是否都达到要求了
if (element.bool) {
clearInterval(element.timer);
//回调函数是否存在
if (fn) {
//执行回调函数
fn();
}
}
}, 18);
}
</script>
</body>
</html>
◆改进兼容性缓速框架(高级版)-透明度样式<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>改进兼容性缓速框架(高级版)-透明度样式</title>
<style type="text/css">
.box {
height: 200px;
background-color: #eee;
position: relative;
padding-left: 100px;
padding-top: 20px;
}
#box1 {
width: 80px;
height: 80px;
background-color: #701;
position: absolute;
top: 60px;
left: 100px;
/*box-shadow: #a01 0px 0px 80px 10px;*/
border-radius: 1px;
}
</style>
</head>
<body>
<div class="box">
<button>变成圆球向右滚,滚完之后再回来,恢复原样</button>
<div id="box1"></div>
</div>
<script>
//需求:
// 点击按钮之后,
// 1.小方块儿先向右缓速滚动,
// 边滚动边变成小圆球,
// 并且透明从1变成0.5
// 2.再向下缓速移动,
// 边滚动边变成小方块儿
// 并且透明从0.5变成1
// 3.再向左移动,
// 边滚动边变成小圆球,
// 并且透明度从1变成0.5
// 4.最后向上移动
// 边滚边回复最初的模样
//思路:
// 在有些主流浏览器上,
// 直接获取border-radius的内嵌样式与外链样式的属性值,
// 所以需要重新封装一个getStyle方法,
// 从而能够获取到border-radius,
// 然后重新封装一遍缓速动画的框架,
// ★并且在缓速框架中兼容opacity透明度
// 透明度在获取值时采取*100的方式
// 赋值采取/100的方式,
// 这么做一方面是为了兼容IE678,
// 一方面是为了更好的计算,
// 因为小数在计算时会出现精度丢失的问题
// *100变成整数更利于运算
// 传递的参数:
// 1.需要缓速改变样式的元素对象、
// 2.已经样式参数集合对象(样式json)
// 3.回调函数,当缓速动画结束之后再执行的方法
//步骤:
//1.老三步
//2.封装getStyle兼容border-radius的框架
//3.封装animate缓速框架
//1.老三步
//1.1获取事件源及相关元素对象
var box = document.getElementsByTagName("div")[0];
var btn = box.children[0];
var box1 = box.children[1];
//1.2绑定事件源
btn.onclick = function () {
//1.3书写事件驱动程序
// animate(box1, {opacity: 50}, function () {
// animate(box1, {opacity: 100});
// });
animate(box1, {left: 1000, "border-radius": 50, opacity: 50}, function () {
animate(box1, {top: 500, "border-radius": 1, opacity: 100}, function () {
animate(box1, {left: 100, "border-radius": 50, opacity: 50}, function () {
animate(box1, {top: 60, "border-radius": 1, opacity: 100}, null);
});
});
});
}
//2.封装getStyle兼容border-radius的框架
/**
* 功能:获取兼容borderRadius的getStyle框架
* @param elemnet
* @param attribute
* @returns {string}
*/
function getStyle(elemnet, attribute) {
// 左边||右边
// 左边在有些主流浏览器上获取不到内嵌式和外链式以及行内式的border-radius
// 右边只能够获取到行内式的border-radius
// 所以无论是左边还是右边,在某些浏览器上 肯定获取不到内嵌式和外链式的 border-radius
// 当左边和右边都获取不到时,返回值都是""空字符串,于是就判断一下 是否是border-radius
var sty = (elemnet.currentStyle
?
elemnet.currentStyle[attribute]
:
window.getComputedStyle(elemnet, null)[attribute]
) || elemnet.style[attribute];
//判断获取到的值是否为空字符串
if ("" == sty) {
switch (attribute) {
case "borderRadius":
case "border-radius":
(sty = elemnet.currentStyle
?
elemnet.currentStyle["border-top-left-radius"]
:
window.getComputedStyle(elemnet, null)["border-top-left-radius"]);
break;
default:
sty;
break;
}
}
return sty;
}
//3.封装animate缓速框架
/**
* 功能:缓速改变元素的样式属性值 达到缓速动画的效果
* @param element
* @param styleJson
* @param fn
*/
function animate(element, styleJson, fn) {
//使用定时器之前必须先清除定时器
clearInterval(element.timer);
//开始使用定时器
element.timer = setInterval(function () {
//开闭思想 当每一个样式对象的成员都达到目标时
element.bool = true;
//遍历需要变化的每一个样式对象成员
for (var key in styleJson) {
//key 就是要变化的样式属性名
//styleJson[key] 就是要变化的样式的属性的目标值
//首先防止 突发情况的发生
//例如:按住ctrl键然后鼠标滑轮滚动
// 导致getStyle获取到的值本来没有小数,
// 变得带有小数了,解决这个问题的方法是
// 先替换掉px,然后再向上取整即可,
// 就算你本来的值是有小数的,
// 但是向上取整在整个动画中的改变也是没什么的。
// 如果使用parseInt会导致getStyle获取到的值为0.9时
// 变成0,所以不用parseInt向下取整。
// element.leader = Math.ceil(getStyle(element, key).replace("px", "") / 1) || 0;
//如果值为透明度时
if (key == "opacity") {
element.leader = 100 * (getStyle(element, key).replace("px", "") / 1 || 1);
} else {
element.leader = Math.ceil(getStyle(element, key).replace("px", "") / 1) || 0;
}
//缓速步长的第一次获取
element.speed = (styleJson[key] - element.leader) / 10;
//缓速步长的第二次计算
element.speed = element.speed > 0 ? Math.ceil(element.speed) : Math.floor(element.speed);
//只剩一步之遥时
if (Math.abs(styleJson[key] - element.leader) <= Math.abs(element.speed)) {
//如果值为透明度时
if (key == "opacity") {
element.style[key] = styleJson[key] / 100;
element.style["fliter"] = "alpha(opacity=" + styleJson[key] + ")";
continue;
}
element.style[key] = styleJson[key] + "px";
continue;
} else {
//只要有一个样式对象的成员没有达到目标
// 这个清除定时器的bool值就为false
element.bool = false;
}
//如果值为透明度时
if (key == "opacity") {
element.style[key] = (element.leader + element.speed) / 100;
element.style["fliter"] = "alpha(opacity=" + (element.leader + element.speed) + ")";
continue;
}
//开始移动
element.style[key] = element.leader + element.speed + "px";
}
console.log(1);//测试定时器有没有停下来
//是否都达到要求了
if (element.bool) {
clearInterval(element.timer);
//回调函数是否存在
if (fn) {
//执行回调函数
fn();
}
}
}, 18);
}
</script>
</body>
</html>
◆改进兼容性缓速框架(高级版)-层级的改变<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>改进兼容性缓速框架(高级版)-层级的改变</title>
<style type="text/css">
.box {
height: 200px;
background-color: #eee;
position: relative;
padding-left: 100px;
padding-top: 20px;
}
#box1 {
width: 80px;
height: 80px;
background-color: #701;
position: absolute;
top: 60px;
left: 100px;
/*box-shadow: #a01 0px 0px 80px 10px;*/
border-radius: 1px;
}
</style>
</head>
<body>
<div class="box">
<button>变成圆球向右滚,滚完之后再回来,恢复原样</button>
<div id="box1"></div>
</div>
<script>
//需求:
// 点击按钮之后,
// 1.小方块儿先向右缓速滚动,
// 边滚动边变成小圆球,
// 并且透明从1变成0.5
// 2.再向下缓速移动,
// 边滚动边变成小方块儿
// 并且透明从0.5变成1
// 3.再向左移动,
// 边滚动边变成小圆球,
// 并且透明度从1变成0.5
// 4.最后向上移动
// 边滚边回复最初的模样
// 5.慢慢改变层级
//思路:
// 在有些主流浏览器上,
// 直接获取border-radius的内嵌样式与外链样式的属性值,
// 所以需要重新封装一个getStyle方法,
// 从而能够获取到border-radius,
// 然后重新封装一遍缓速动画的框架,
// ★并且在缓速框架中兼容opacity透明度
// 透明度在获取值时采取*100的方式
// 赋值采取/100的方式,
// 这么做一方面是为了兼容IE678,
// 一方面是为了更好的计算,
// 因为小数在计算时会出现精度丢失的问题
// *100变成整数更利于运算
// 传递的参数:
// 1.需要缓速改变样式的元素对象、
// 2.已经样式参数集合对象(样式json)
// 3.回调函数,当缓速动画结束之后再执行的方法
//步骤:
//1.老三步
//2.封装getStyle兼容border-radius的框架
//3.封装animate缓速框架
//1.老三步
//1.1获取事件源及相关元素对象
var box = document.getElementsByTagName("div")[0];
var btn = box.children[0];
var box1 = box.children[1];
//1.2绑定事件源
btn.onclick = function () {
//1.3书写事件驱动程序
// animate(box1, {opacity: 50}, function () {
// animate(box1, {opacity: 100});
// });
animate(box1, {left: 1000, "border-radius": 50, opacity: 50,zIndex:999}, function () {
animate(box1, {top: 500, "border-radius": 1, opacity: 100,zIndex:1}, function () {
animate(box1, {left: 100, "border-radius": 50, opacity: 50,zIndex:999}, function () {
animate(box1, {top: 60, "border-radius": 1, opacity: 100,zIndex:1}, null);
});
});
});
}
//2.封装getStyle兼容border-radius的框架
/**
* 功能:获取兼容borderRadius的getStyle框架
* @param elemnet
* @param attribute
* @returns {string}
*/
function getStyle(elemnet, attribute) {
// 左边||右边
// 左边在有些主流浏览器上获取不到内嵌式和外链式以及行内式的border-radius
// 右边只能够获取到行内式的border-radius
// 所以无论是左边还是右边,在某些浏览器上 肯定获取不到内嵌式和外链式的 border-radius
// 当左边和右边都获取不到时,返回值都是""空字符串,于是就判断一下 是否是border-radius
var sty = (elemnet.currentStyle
?
elemnet.currentStyle[attribute]
:
window.getComputedStyle(elemnet, null)[attribute]
) || elemnet.style[attribute];
//判断获取到的值是否为空字符串
if ("" == sty) {
switch (attribute) {
case "borderRadius":
case "border-radius":
(sty = elemnet.currentStyle
?
elemnet.currentStyle["border-top-left-radius"]
:
window.getComputedStyle(elemnet, null)["border-top-left-radius"]);
break;
default:
sty;
break;
}
}
return sty;
}
//3.封装animate缓速框架
/**
* 功能:缓速改变元素的样式属性值 达到缓速动画的效果
* @param element
* @param styleJson
* @param fn
*/
function animate(element, styleJson, fn) {
//使用定时器之前必须先清除定时器
clearInterval(element.timer);
//开始使用定时器
element.timer = setInterval(function () {
//开闭思想 当每一个样式对象的成员都达到目标时
element.bool = true;
//遍历需要变化的每一个样式对象成员
for (var key in styleJson) {
//key 就是要变化的样式属性名
//styleJson[key] 就是要变化的样式的属性的目标值
//首先防止 突发情况的发生
//例如:按住ctrl键然后鼠标滑轮滚动
// 导致getStyle获取到的值本来没有小数,
// 变得带有小数了,解决这个问题的方法是
// 先替换掉px,然后再向上取整即可,
// 就算你本来的值是有小数的,
// 但是向上取整在整个动画中的改变也是没什么的。
// 如果使用parseInt会导致getStyle获取到的值为0.9时
// 变成0,所以不用parseInt向下取整。
// element.leader = Math.ceil(getStyle(element, key).replace("px", "") / 1) || 0;
//如果值为透明度时
if (key == "opacity") {
element.leader = 100 * (getStyle(element, key).replace("px", "") / 1 || 1);
} else {
element.leader = Math.ceil(getStyle(element, key).replace("px", "") / 1) || 0;
}
//缓速步长的第一次获取
element.speed = (styleJson[key] - element.leader) / 10;
//缓速步长的第二次计算
element.speed = element.speed > 0 ? Math.ceil(element.speed) : Math.floor(element.speed);
//只剩一步之遥时
if (Math.abs(styleJson[key] - element.leader) <= Math.abs(element.speed)) {
//如果值为透明度时
if (key == "opacity") {
element.style[key] = styleJson[key] / 100;
element.style["fliter"] = "alpha(opacity=" + styleJson[key] + ")";
continue;
} else if (key == "z-index" || key == "zIndex") {//如果为层级时
element.style[key] = styleJson[key];
continue;
}
element.style[key] = styleJson[key] + "px";
continue;
} else {
//只要有一个样式对象的成员没有达到目标
// 这个清除定时器的bool值就为false
element.bool = false;
}
//如果值为透明度时
if (key == "opacity") {
element.style[key] = (element.leader + element.speed) / 100;
element.style["fliter"] = "alpha(opacity=" + (element.leader + element.speed) + ")";
continue;
} else if (key == "z-index" || key == "zIndex") { //如果为层级时
element.style[key] = element.leader + element.speed;
continue;
}
//开始移动
element.style[key] = element.leader + element.speed + "px";
}
console.log(1);//测试定时器有没有停下来
//是否都达到要求了
if (element.bool) {
clearInterval(element.timer);
//回调函数是否存在
if (fn) {
//执行回调函数
fn();
}
}
}, 18);
}
</script>
</body>
</html>