当前位置: 首页 > 编程日记 > 正文

Javascript使用三大家族和事件来DIY动画效果相关笔记(一)

1.offset家族

◆offsetWidth和offsetHeight表示盒子真实的宽度高度,这个真实的宽度包括 四周的边框、四周的padding、及定义的宽度高度或内容撑开的高度和宽度,可以用来检测盒子实际的大小,属性也是只读不可写的,返回的是不带单位的数值,返回值为number类型。

◆offsetLeft和offsetTop表示当前盒子在定位后距离定位了的父容器的左偏移与上偏移,该属性是只读的不能写,如果父容器没有定位属性(主要是非静态定位),那么就以距离自己最近的父系的非静态定位的盒子为基准,其实和样式中的非静态定位一样的,实在找不到就以浏览器的起始点为基准,所以也许浏览器的起始点是用了非静态定位的,offsetLeft和offsetTop如果在当前盒子没有定位时,那么就默认一浏览器的起始点为基准了,返回的是不带单位的数值,返回值为number类型。

◆offsetParent表示当前盒子距离最近的父系非静态的定位盒子元素,offsetParent返回的是一个元素节点,如果父系盒子中都没有非静态定位,那么就默认返回body节点了。

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>offset家族</title><style type="text/css">#box {border: 5px solid #0f0;padding: 10px;width: 200px;height: 200px;background-color: #f00;position: relative;}#box1 {position: absolute;left: 20px;top: 20px;width: 60px;height: 60px;background-color: #0f0;}#box2 {position: absolute;left: 100px;top: 100px;width: 60px;height: 60px;background-color: #f09;}#box3 {position: absolute;left: 300px;top: 300px;width: 160px;height: 160px;background-color: #901;}</style>
</head>
<body>
<div id="box"><div id="box1"></div><div id="box2"></div>
</div><div id="box3"></div>
<script>/** offsetWidth和offsetHeight* 表示盒子真实的宽度高度,这个真实的宽度包括* 四周的边框、四周的padding、及定义的宽度高度或内容撑开的高度和宽度,* 可以用来检测盒子实际的大小,属性也是只读不可写的,* 返回的是不带单位的数值,返回值为number类型。*/console.log(box.offsetWidth);//盒子实际宽度console.log(box.offsetHeight);//盒子实际高度/** offsetLeft和offsetTop* 表示当前盒子在定位后距离定位了的父容器的左偏移与上偏移,* 该属性是只读的不能写,如果父容器没有定位属性(主要是非静态定位),* 那么就以距离自己最近的父系的非静态定位的盒子为基准,* 其实和样式中的非静态定位一样的,实在找不到就以浏览器的起始点为基准,* 所以也许浏览器的起始点是用了非静态定位的,* offsetLeft和offsetTop如果在当前盒子没有定位时,* 那么就默认一浏览器的起始点为基准了,* 返回的是不带单位的数值,返回值为number类型。*/console.log(box1.offsetLeft);//盒子距离父容器的左偏移console.log(box1.offsetTop);//盒子距离父容器的上偏移/**offsetParent表示当前盒子距离最近的父系非静态的定位盒子元素,* offsetParent返回的是一个元素节点,* 如果父系盒子中都没有非静态定位,* 那么就默认返回body节点了。*/console.log(box2.offsetParent);//box2找到了非静态定位的父容器 返回父容器节点console.log(box3.offsetParent);//box3找不到非静态定位的父容器 返回body节点/**offsetLeft和style.left的区别*◆offsetLeft只读,style.left可读可写。**◆在没有设置行内样式定位等属性时,style.left能获取到的只是空*字符串,而offsetLeft能够获取真实的偏移值。**◆在设置了行内样式定位等属性时,style.left获取到的只是带有单*位的字符串如果200px,而offsetLeft获取还是真实的偏移值如200,*offsetLeft获取到的是number类型的数字。**◆offsetLeft在当前盒子不处于定位的状态下也能够针对浏览器的*起始点来确定偏移值,而style.left在那个时候只能够获取空字符串。**★相同点,在定位的时候二者一样的,都不会去计算非静态定位的*父容器的边框,无论边框多大,都是从padding开始算起的,那个*时候style.left去掉单位转换为数字就等于offsetLeft了。*/</script>
</body>
</html>


2.非静态定位小知识

◆给元素添加非静态定位的定位属性时,你如果不设置它的left和top或者bottom再或者right属性时,他就装作以标准文档流的方式找个位置待着,但是它的确不占空间,很像是左浮动,也许非静态定位不设置left、top、right、bottom属性时就等于float:left;,定位的时候left、top、right、bottom属性不会计算非静态定位的父容器的边框,而是从父容器去除边框之后才正式开始计算的,但是自己如果是有边框的话,会以自己边框最外层作为left、top、right、bottom的起始点也就是(0,0)点,会以这个点与父容器去除边框后的(0,0)点重合,只再根据left、top、right、bottom来确定位置。


3.offsetLeft和style.left的区别

◆offsetLeft只读,style.left可读可写。

◆在没有设置行内样式定位等属性时,style.left能获取到的只是空字符串,而offsetLeft能够获取真实的偏移值。
◆在设置了行内样式定位等属性时,style.left获取到的只是带有单位的字符串如果200px,而offsetLeft获取还是真实的偏移值如200,offsetLeft获取到的是number类型的数字。
◆offsetLeft在当前盒子不处于定位的状态下也能够针对浏览器的起始点来确定偏移值,而style.left在那个时候只能够获取空字符串。

★相同点,在定位的时候二者一样的,都不会去计算非静态定位的父容器的边框,无论边框多大,都是从padding开始算起的,那个时候style.left去掉单位转换为数字就等于offsetLeft了。


4.使用offsetLeft和style.left来DIY动画

◆基础的闪动与匀速移动效果

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>通过offset来实现动画</title><style type="text/css">#div1 {width: 80px;height: 80px;background-color: #f0f;position: absolute;top: 200px;}#div2 {width: 80px;height: 80px;background-color: #f09;position: absolute;top: 400px;}</style>
</head>
<body>
<button id="btn1">瞬间闪动</button>
<button id="btn2">匀速运动</button>
<div id="div1"></div>
<div id="div2"></div>
<script>btn1.addEventListener("click", function () {div1.style.left = "800px";})btn2.addEventListener("click", function () {//定时器,每隔一定的时间向右走一些setInterval(function () {//这么做太麻烦了
//            div2.style.left=parseInt(div2.style.left==""?0:div2.style.left)+10+"px";//动画原理: 盒子未来的位置 = 盒子现在的位置 + 步长;//style.left赋值,用offsetLeft获取值。//style.left获取值不方便很麻烦,首先要设置行内式,如果没有设置行内式获取的是"";//如果不通过判断来重新赋值就容易出现parseInt(style.left)时返回值是NaN//offsetLeft是只读的,每次获取到的值都是number类型的数字。div2.style.left = div2.offsetLeft + 10 + "px";}, 30);})
</script>
</body>
</html>
◆封装基础的匀速动画简单版
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>使用offset封装动画</title><style type="text/css">#box {height: 200px;background-color: #eee;position: relative;}#box1 {width: 100px;height: 100px;position: absolute;top: 50px;background-color: #f09;left: 1312px;}</style>
</head>
<body>
<div><div id="box"><button id="btn1">移动到200</button><button id="btn2">移动到400</button><div id="box1"></div></div><script>var box1 = document.getElementById("box1");var timer = 0;var speed = 10;btn1.onclick = function () {animate(200)}btn2.onclick = function () {animate(400)}function animate(target) {//bug1:当你多点几次的时候会出现 多个定时器同时运行,然后会导致停不下也无法关闭//解决方案:每次执行动画时就停止上一次的动画 清除上一次的动画后再继续本次的动画clearInterval(timer);//bug2:当移动到指定的位置后再点击动画 会让动画继续跑然后还会停不下来 因为已经超过了要移动的位置//解决方案:先判断是否符合距离 然后再执行是否继续移动
//            if(box1.offsetLeft===target)//bug3:如果位移多次自增后无法和指定位置相同,就会导致无法关闭循环定时器而不停下来//解决方案:判断 指定位置target减去偏移offsetLeft是否小于自增距离speed,//          如果小就停止,并且让style.left等于target
//            if (target - box1.offsetLeft < speed) {
//                box1.style.left=target+"px";//bug4:如果当偏移本身就超过了指定的位置,就会出现突然间就跑到指定位置了//解决方案:如果一开始就超过了指定的位置,那么就让它往回跑,达到指定位置// 最重要的是判断正负的距离是否在自增距离的范围内 speed的范围内// 如果在,那么久直接赋值为指定的位置,然后停止循环计时器,终止方法执行//动态改变每次递增的距离  如果跑过了递增的距离就要为负数speed=box1.offsetLeft>target?-10:10;timer = setInterval(function () {//让正负距离不能够超过步长即自增的距离,不管正负if (Math.abs(target - box1.offsetLeft) <= Math.abs(speed)) {box1.style.left=target+"px";clearInterval(timer);return;//终止函数往下进行}box1.style.left = box1.offsetLeft + speed + "px";}, 30)}</script>
</div>
</body>
</html>
◆封装基础的匀速动画正常版
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>使用offset封装动画</title><style type="text/css">#box {height: 300px;background-color: #eee;position: relative;}
/*box1和box2这种颜色搭配很晃眼,很有创意*/#box1 {width: 100px;height: 100px;position: absolute;top: 50px;background-color: #f09;left: 1312px;}#box2 {width: 100px;height: 100px;position: absolute;top: 150px;background-color: #90f;left: 0px;}</style>
</head>
<body>
<div><div id="box"><button id="btn1">移动到200</button><button id="btn2">移动到400</button><div id="box1"></div><div id="box2"></div></div><script>var box1 = document.getElementById("box1");var box2 = document.getElementById("box2");//不需要自定义 定时器 和 步数了 直接给元素添加这两个属性即可//        var timer = 0;//        var speed = 10;btn1.onclick = function () {animate(box1, 200);//直接传递元素即可animate(box2, 200);//直接传递元素即可}btn2.onclick = function () {animate(box1, 400)//直接传递元素即可animate(box2, 400)//直接传递元素即可}function animate(element, target) {//bug1:当你多点几次的时候会出现 多个定时器同时运行,然后会导致停不下也无法关闭//解决方案:每次执行动画时就停止上一次的动画 清除上一次的动画后再继续本次的动画clearInterval(element.timer);//这样每个元素都有一个独立的定时器的计数器了//bug2:当移动到指定的位置后再点击动画 会让动画继续跑然后还会停不下来 因为已经超过了要移动的位置//解决方案:先判断是否符合距离 然后再执行是否继续移动
//            if(box1.offsetLeft===target)//bug3:如果位移多次自增后无法和指定位置相同,就会导致无法关闭循环定时器而不停下来//解决方案:判断 指定位置target减去偏移offsetLeft是否小于自增距离speed,//          如果小就停止,并且让style.left等于target
//            if (target - box1.offsetLeft < speed) {
//                box1.style.left=target+"px";//bug4:如果当偏移本身就超过了指定的位置,就会出现突然间就跑到指定位置了//解决方案:如果一开始就超过了指定的位置,那么就让它往回跑,达到指定位置// 最重要的是判断正负的距离是否在自增距离的范围内 speed的范围内// 如果在,那么久直接赋值为指定的位置,然后停止循环计时器,终止方法执行//动态改变每次递增的距离  如果跑过了递增的距离就要为负数element.speed = element.offsetLeft > target ? -10 : 10;element.timer = setInterval(function () {//让正负距离不能够超过步长即自增的距离,不管正负if (Math.abs(target - element.offsetLeft) <= Math.abs(element.speed)) {element.style.left = target + "px";clearInterval(element.timer);return;//终止函数往下进行}element.style.left = element.offsetLeft + element.speed + "px";}, 30)}</script>
</div>
</body>
</html>


5.图片轮播基础之匀速轮播

◆使用封装的匀速动画来DIY滑动轮播图,也就是鼠标移动到123456这些数字上后,图片以匀速滑动的方式进行切换。

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>使用封装的匀速动画制作滑动轮播图</title><style type="text/css">body, ul, li, div, span, img {padding: 0;margin: 0;}img {border: 0 none;vertical-align: top;}.box {width: 490px;height: 170px;padding: 5px;border: 1px solid #f09;margin: 100px auto;}.inner {width: 490px;height: 170px;position: relative;overflow: hidden;cursor: pointer;}ul {list-style: none;width: 500%;position: absolute;left: 0;}li {float: left;}.square {position: absolute;bottom: 10px;right: 10px;}.square span {display: inline-block;width: 16px;height: 16px;line-height: 14px;border: 1px solid #ccc;background-color: #fff;text-align: center;margin-left: 5px;cursor: pointer;}.square .current {background-color: #f00;color: #fff;}</style>
</head>
<body>
<div class="box"><div class="inner" id="inner"><ul><li><img src="images1/01.jpg"></li><li><img src="images1/02.jpg"></li><li><img src="images1/03.jpg"></li><li><img src="images1/04.jpg"></li><li><img src="images1/05.jpg"></li></ul><div class="square"><span class="current">1</span><span>2</span><span>3</span><span>4</span><span>5</span></div></div>
</div>
<script>//需求:当点击 轮播图中的 span时 span要高亮显示并且// 还要让图片框中的图片移动到相应的图片上//思路://  1.使用循环来遍历span,给每一个span绑定鼠标移入的事件//  2.当鼠标移入span时就清除全部span的className属性//  3.然后给自己加上 高亮的class(排他思想 先杀死全部 然后复活自己)//  4.给每个元素添加一个index属性,作为图片的相应索引//  5.调用自己做的匀速动画框架,传递元素和相应的指定的位置(-(图片索引*图片宽度))//步骤://  1.获取事件源及相关元素对象//  2.绑定事件//  3.书写事件驱动程序//  1.获取事件源及相关元素对象var inner = document.getElementById("inner");var ul = inner.firstElementChild || inner.firstChild;var spanArr = inner.children[1].children;//  2.绑定事件for (var i = 0; i < spanArr.length; i++) {//给每个元素添加一个index属性spanArr[i].index=i;spanArr[i].onmouseover= function () {//清除全部span的className属性for(var j=0;j < spanArr.length; j++){spanArr[j].className="";}//给自己加上 高亮的class(排他思想 先杀死全部 然后复活自己)this.className="current";//调用自己做的匀速动画框架,传递元素和相应的指定的位置(-(图片索引*图片宽度))
//            animate(ul,-this.index*490);animate(ul,-this.index*inner.offsetWidth);//动画的本质就是左右移动元素,移动至指定的位置,// 由于元素的父容器设置了高宽也设置了overflow:hiden// 所以你只能看到指定部分,于是就是轮播了。}}//  3.书写事件驱动程序//自己制作的匀速动画的框架function animate(element, target) {//bug1:当你多点几次的时候会出现 多个定时器同时运行,然后会导致停不下也无法关闭//解决方案:每次执行动画时就停止上一次的动画 清除上一次的动画后再继续本次的动画clearInterval(element.timer);//这样每个元素都有一个独立的定时器的计数器了//bug2:当移动到指定的位置后再点击动画 会让动画继续跑然后还会停不下来 因为已经超过了要移动的位置//解决方案:先判断是否符合距离 然后再执行是否继续移动
//            if(box1.offsetLeft===target)//bug3:如果位移多次自增后无法和指定位置相同,就会导致无法关闭循环定时器而不停下来//解决方案:判断 指定位置target减去偏移offsetLeft是否小于自增距离speed,//          如果小就停止,并且让style.left等于target
//            if (target - box1.offsetLeft < speed) {
//                box1.style.left=target+"px";//bug4:如果当偏移本身就超过了指定的位置,就会出现突然间就跑到指定位置了//解决方案:如果一开始就超过了指定的位置,那么就让它往回跑,达到指定位置// 最重要的是判断正负的距离是否在自增距离的范围内 speed的范围内// 如果在,那么久直接赋值为指定的位置,然后停止循环计时器,终止方法执行//动态改变每次递增的距离  如果跑过了递增的距离就要为负数element.speed = element.offsetLeft > target ? -10 : 10;element.timer = setInterval(function () {//让正负距离不能够超过步长即自增的距离,不管正负if (Math.abs(target - element.offsetLeft) <= Math.abs(element.speed)) {element.style.left = target + "px";clearInterval(element.timer);return;//终止函数往下进行}element.style.left = element.offsetLeft + element.speed + "px";}, 10)}</script>
</body>
</html>
◆使用封装的匀速动画来DIY左右轮播图,也就是点击左右按钮的时候,图片左右匀速切换。
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>使用封装的匀速动画制作左右轮播图</title><style type="text/css">body, ul, li, div, span, img {padding: 0;margin: 0;}img {border: 0 none;vertical-align: top;}.box {width: 520px;height: 280px;padding: 5px;border: 1px solid #f09;margin: 100px auto;}.inner {width: 520px;height: 280px;position: relative;overflow: hidden;cursor: pointer;}ul {list-style: none;width: 500%;position: absolute;left: 0;}li {float: left;}/*鼠标移动到图片框时 就显示*/.inner:hover .square {display: block;}.square {width: 100%;position: absolute;top:50%;margin-top:-20px;display: none;/*默认不显示*/}.square span {display: block;width: 30px;height: 60px;background-color: #fff;font:500 25px/60px "consolas";text-align: center;cursor: pointer;color:#fff;background-color: rgba(0,0,0,0.3);}#sq-left {float:left;}#sq-right {float: right;}/*.square .current {*//*background-color: #f00;*//*color: #fff;*//*}*/</style>
</head>
<body>
<div class="box"><div class="inner" id="inner"><ul><li><img src="images2/1.jpg"></li><li><img src="images2/2.jpg"></li><li><img src="images2/3.jpg"></li><li><img src="images2/4.jpg"></li><li><img src="images2/5.jpg"></li></ul><div class="square"><span id="sq-left"><</span><span id="sq-right">></span></div></div>
</div>
<script>//需求:当点击左箭头时,图片向左切换一张,//      切换到第一张时就弹出 已经是第一张,//      便不能再切换往前切换了,点击右箭头时//      图片向右切换一张,切换到最后一张时,//      就弹出 已经是最后一张了,便不能再往后切换了//思路:给左右箭头绑定单击事件,点击左箭头或者右箭头,就让移动的距离增大,//      增大的倍数就是 图片的索引,每次点击左右箭头之前,先进行判断,//      左箭头判断是否小于0,右箭头判断是否大于最大索引//步骤:// 1.   获取事件源及相关元素对象// 2.   绑定事件// 3.   书写事件驱动程序// 1.   获取事件源及相关元素对象var inner=document.getElementById("inner");var ul=inner.children[0];var sqleft=document.getElementById('sq-left');var sqright=document.getElementById('sq-right');// 2.   绑定事件var index=0;//图片索引sqleft.onclick= function () {// 3.   书写事件驱动程序index--;//索引减减if(index<0){index=0;alert("已经是第一张了");return;}animate(ul, -inner.offsetWidth*index);}sqright.onclick= function () {// 3.   书写事件驱动程序index++;//索引加加if(index>ul.children.length-1){index=ul.children.length-1;alert("已经是最后一张了");return;}animate(ul, -inner.offsetWidth*index);}// 3.   书写事件驱动程序//自己制作的匀速动画的框架function animate(element, target) {//bug1:当你多点几次的时候会出现 多个定时器同时运行,然后会导致停不下也无法关闭//解决方案:每次执行动画时就停止上一次的动画 清除上一次的动画后再继续本次的动画clearInterval(element.timer);//这样每个元素都有一个独立的定时器的计数器了//bug2:当移动到指定的位置后再点击动画 会让动画继续跑然后还会停不下来 因为已经超过了要移动的位置//解决方案:先判断是否符合距离 然后再执行是否继续移动
//            if(box1.offsetLeft===target)//bug3:如果位移多次自增后无法和指定位置相同,就会导致无法关闭循环定时器而不停下来//解决方案:判断 指定位置target减去偏移offsetLeft是否小于自增距离speed,//          如果小就停止,并且让style.left等于target
//            if (target - box1.offsetLeft < speed) {
//                box1.style.left=target+"px";//bug4:如果当偏移本身就超过了指定的位置,就会出现突然间就跑到指定位置了//解决方案:如果一开始就超过了指定的位置,那么就让它往回跑,达到指定位置// 最重要的是判断正负的距离是否在自增距离的范围内 speed的范围内// 如果在,那么久直接赋值为指定的位置,然后停止循环计时器,终止方法执行//动态改变每次递增的距离  如果跑过了递增的距离就要为负数element.speed = element.offsetLeft > target ? -10 : 10;element.timer = setInterval(function () {//让正负距离不能够超过步长即自增的距离,不管正负if (Math.abs(target - element.offsetLeft) <= Math.abs(element.speed)) {element.style.left = target + "px";clearInterval(element.timer);return;//终止函数往下进行}element.style.left = element.offsetLeft + element.speed + "px";}, 10)}</script>
</body>
</html>

◆使用封装的匀速动画来DIY无缝轮播图,轮播的本质就是来回移动图片的位置,无缝轮播其实是多加了一张图片在最后面,当你切换到最后一张图片时,最后一张图片再往后切换时,实际上会瞬间切换到第一张然后再继续切换匀速切换到第二张,因为最后一张和第一张一模一样,所以瞬间切换的过程根本看不出来,所以就像很完整的无缝轮播了。

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>使用封装的匀速动画制作无缝轮播图</title><style type="text/css">body, ul, ol, li, div, span, img {padding: 0;margin: 0;}img {border: 0 none;vertical-align: top;}.box {width: 500px;height: 200px;padding: 5px;border: 1px solid #f09;margin: 100px auto;}.inner {width: 500px;height: 200px;position: relative;overflow: hidden;/*cursor: pointer;*/}ul {list-style: none;width: 620%;position: absolute;left: 0;}ul li {float: left;}/*鼠标移动到图片框时 就显示*/.inner:hover .square {display: block;}.square {width: 100%;position: absolute;top: 50%;margin-top: -20px;display: none;/*默认不显示*/}.square span {display: block;width: 30px;height: 60px;background-color: #fff;font: 500 25px/60px "consolas";text-align: center;cursor: pointer;color: #fff;background-color: rgba(0, 0, 0, 0.3);}#sq-left {float: left;}#sq-right {float: right;}ol {position: absolute;bottom: 10px;right: 10px;}ol li {display: inline-block;width: 16px;height: 16px;line-height: 14px;font-size: 12px;border: 1px solid #ccc;background-color: #fff;text-align: center;margin-left: 5px;cursor: pointer;}ol .current {background-color: #f00;color: #fff;}</style>
</head>
<body>
<div class="box"><div class="inner" id="inner"><ul><li><img src="images3/1.jpg"></li><li><img src="images3/2.jpg"></li><li><img src="images3/3.jpg"></li><li><img src="images3/4.jpg"></li><li><img src="images3/5.jpg"></li><li><img src="images3/1.jpg"></li></ul><ol><li class="current">1</li><li>2</li><li>3</li><li>4</li><li>5</li></ol><div class="square"><span id="sq-left"><</span><span id="sq-right">></span></div></div>
</div>
<script>//需求:// 1.鼠标移动到带有小编号的方块儿时,小方块儿高亮显示并且同时切换到对应的图片// 2.让图片从左至右进行自动轮播,小方块儿的高亮样式也会跟着切换// 3.鼠标移动到图片框中时,就停止自动轮播// 4.点击左右箭头 切换到对应的图片// 5.// 6.//思路://  1.给所有小方块儿绑定鼠标移入的事件,//   移入时清除所有的高亮样式然后给当前小方块儿添加高亮样式,//   使用自己封装的匀速动画,让图片移动到指定位置//  2.封装一个方法,让让图片自动移动到指定位置,小方块儿的高亮样式也会跟着图片切换//  3.给图片框设置鼠标移入移出事件,移入的时候就清除执行自动轮播的方法中的定时器//    移出时执行自动轮播的定时器//  4.给左右箭头绑定单击事件,点击左右箭头时,让方块儿高样式与图片的位置同时切换//步骤://1.获取事件源 及相关对象//2.绑定事件//3.书写事件驱动程序//1.获取事件源 及相关对象var inner = document.getElementById("inner");var ul = inner.children[0];var olArr = inner.children[1].children;//        var square=inner.lastElementChild ||inner.lastChild;//        var sqleft=square.children[0];//        var sqright=square.children[1];var sqleft = document.getElementById("sq-left");var sqright = document.getElementById("sq-right");//2.绑定事件 循环给小方块儿绑定移入事件for (var i = 0; i < olArr.length; i++) {//给每一个ol中的li添加一个index属性,代表当前li的索引值olArr[i].index = i;olArr[i].onmousemove = function () {//3.书写事件驱动程序for (var j = 0; j < olArr.length; j++) {olArr[j].className = "";}this.className = "current";//使用动画移动距离animate(ul, -this.index * inner.offsetWidth);//与自动轮播 的 图片索引及方块儿同步key = this.index;sqindex = this.index;}}//2.绑定事件 给图片框绑定移入移出事件inner.onmousemove = function () {//清除定时器clearInterval(timer);}inner.onmouseout = function () {//调用循环计数器timer = setInterval(autoplay, 1000);}//2.绑定事件 给左右箭头绑定移入移出事件sqleft.onclick = function () {rautoplay();}sqright.onclick = function () {//自动轮播就是从左往右的autoplay();}/*** 自动轮播的方法*/var timer = 0;//全局的定时器 计数器var key = 0;//图片的索引var sqindex = 0;//方块儿的索引function autoplay() {key++;//图片索引递增//图片比方块儿多一个  当图片在第6张时 方块儿跳到了第一个if (key > olArr.length) {ul.style.left = 0+"px";//瞬间切换到第一张  看不出来 因为第六张和第一张一模一样key = 1;//跳到第二张,因为这个时候方块儿也会跳到第二个}//使用动画移动距离animate(ul, -key * inner.offsetWidth);sqindex++;//方块儿的索引递增if (sqindex > olArr.length - 1) {sqindex = 0;}for (var i = 0; i < olArr.length; i++) {olArr[i].className = "";}olArr[sqindex].className = "current";}//调用循环计数器timer = setInterval(autoplay, 1000);//3.书写事件驱动程序/***反方向的自动轮播方法*/function rautoplay() {key--;//图片索引递减//图片比方块儿多一个  当图片在第1张时 方块儿跳到了最后一个if (key < 0) {ul.style.left = -olArr.length * inner.offsetWidth+"px";//瞬间切换到最后一张  看不出来 因为第六张和第一张一模一样key = olArr.length-1;//跳到倒数第二张,因为这个时候方块儿也会跳到最后一个}//使用动画移动距离animate(ul, -key * inner.offsetWidth);sqindex--;//方块儿的索引递减if (sqindex < 0) {sqindex = olArr.length - 1;}for (var i = 0; i < olArr.length; i++) {olArr[i].className = "";}olArr[sqindex].className = "current";}//自己制作的匀速动画的框架function animate(element, target) {//bug1:当你多点几次的时候会出现 多个定时器同时运行,然后会导致停不下也无法关闭//解决方案:每次执行动画时就停止上一次的动画 清除上一次的动画后再继续本次的动画clearInterval(element.timer);//这样每个元素都有一个独立的定时器的计数器了//bug2:当移动到指定的位置后再点击动画 会让动画继续跑然后还会停不下来 因为已经超过了要移动的位置//解决方案:先判断是否符合距离 然后再执行是否继续移动
//            if(box1.offsetLeft===target)//bug3:如果位移多次自增后无法和指定位置相同,就会导致无法关闭循环定时器而不停下来//解决方案:判断 指定位置target减去偏移offsetLeft是否小于自增距离speed,//          如果小就停止,并且让style.left等于target
//            if (target - box1.offsetLeft < speed) {
//                box1.style.left=target+"px";//bug4:如果当偏移本身就超过了指定的位置,就会出现突然间就跑到指定位置了//解决方案:如果一开始就超过了指定的位置,那么就让它往回跑,达到指定位置// 最重要的是判断正负的距离是否在自增距离的范围内 speed的范围内// 如果在,那么久直接赋值为指定的位置,然后停止循环计时器,终止方法执行//动态改变每次递增的距离  如果跑过了递增的距离就要为负数element.speed = element.offsetLeft > target ? -10 : 10;element.timer = setInterval(function () {//让正负距离不能够超过步长即自增的距离,不管正负if (Math.abs(target - element.offsetLeft) <= Math.abs(element.speed)) {element.style.left = target + "px";clearInterval(element.timer);return;//终止函数往下进行}element.style.left = element.offsetLeft + element.speed + "px";}, 10)}</script>
</body>
</html>

◆在使用定时器的时候,最好让每一个定时器的编号都独立起来,这样就不容易出现关闭定时器时把别的定时器给关掉了,如给被一个元素弄一个timer属性,当给这个元素设置定时器时就能够让这个元素独享一个定时器了,不会把其它定时器给关掉,定时器的编号timer不要是全局的,否则就会出现关闭定时器时把最后一个定时器关闭,而其他定时器无法关闭。

◆谷歌浏览器的小bug,就是当你给页面元素定位为0时,你会发现,如果让style.left增加,第二次的时候,你会发现offsetLeft会比style.left多1,这个bug会导致动画比你预期的要难,就是根本停不下来,原因是你在轮播之后让页面进行缩放了,才导致这个现象发生。


转载于:https://www.cnblogs.com/jwlLWJ2018/p/9247740.html

相关文章:

React 学习

一、搭建webpack4.x环境 1.创建工程文件夹&#xff08;ReactDemo&#xff09; 2.在工程文件夹下&#xff0c;快速初始化项目 npm init -y // 创建一个package.json文件 3.在工程文件夹下&#xff0c;创建源码文件夹&#xff08;src&#xff09;和编译打包文件夹&#xf…

python创建mysql数据库_python 怎么创建create mysql的数据库

展开全部 我采用的是MySQLdb操作的MYSQL数据库。先来一个简单的例2113子吧&#xff1a; import MySQLdb try: connMySQLdb.connect(hostlocalhost,userroot,passwdroot,dbtest,port3306) curconn.cursor() cur.execute(select * from user) cur.close() conn.close() except My…

杂谈---改变个人习惯

在提升编码技术的过程&#xff0c;自己也在生活中学到了很多。发现了自己的很多缺陷&#xff1a;不够勇敢、不够冒险、骄傲的无厘头&#xff0c;还有自己对情绪的掌控远没有自己想象的那么有火候&#xff0c;这段时间也得好好谢谢她&#xff0c;要不然我压根意识不到问题有多严…

ldconcig详解

ldconfig是一个动态链接库管理命令&#xff0c;为了让动态链接库为系统所共享,还需运行动态链接库的管理命令--ldconfigldconfig 命令的用途,主要是在默认搜寻目录(/lib和/usr/lib)以及动态库配置文件/etc/ld.so.conf内所列的目录下,搜索出可共享的动态链接库(格式如前介绍,lib…

第3章—高级装配—条件化的Bean

条件化的Bean 通过活动的profile&#xff0c;我们可以获得不同的Bean。Spring 4提供了一个更通用的基于条件的Bean的创建方式&#xff0c;即使用Conditional注解。 Conditional根据满足某个特定的条件创建一个特定的Bean。比如&#xff0c;当某一个jar包在一个类路径下时&#…

c#委托与事件(二)

这篇博客是在上篇的基础开始讲述了一下委托的一些用法&#xff0c;首先我举一个例子说明了一下前面章节的知识点&#xff0c;接下来我说了将方法作为参数传递的一个案例&#xff0c;接下来实现了一个委托实现冒泡排序的方法&#xff0c;如果你们和我一样正在学习&#xff0c;希…

互联网公司java面试题(一)

1、JDK和JRE区别&#xff1f; JDK是整个JAVA的核心&#xff0c;包括了Java运行环境JRE&#xff0c;一堆Java工具和Java基础的类库。通过JDK开发人员将源码文件(java文件)编译成字节码文件(class文 件)。JRE是Java运行环境&#xff0c;不含开发环境&#xff0c;即没有编译器和调…

python属于哪种类型的语言_Python是什么类型的编程语言,有什么特性

由于近几年人工智能的不断发展&#xff0c;Python也跟着火了&#xff0c;因为Python是深度学习技术的主流应用编程语言。同时它的应用场景很多&#xff0c;被称为“胶水语言”。下面给大家科普一下Python这门神奇的编程语言&#xff0c;以及语言特性&#xff0c;帮大家更清晰的…

Linux下C语言线程池的实现(1)

http://hi.baidu.com/lingiloveyou/blog/item/21e57cf3322a6b40342accc7.html 什么时候需要创建线程池呢&#xff1f;简单的说&#xff0c;如果一个应用需要频繁的创建和销毁线程&#xff0c;而任务执行的时间又非常短&#xff0c;这样线程创建和销毁的带来的开销就不容忽视&am…

一篇简单易懂的原理文章,让你把JVM玩弄与手掌之中

jvm原理 Java虚拟机是整个java平台的基石&#xff0c;是java技术实现硬件无关和操作系统无关的关键环节&#xff0c;是java语言生成极小体积的编译代码的运行平台&#xff0c;是保护用户机器免受恶意代码侵袭的保护屏障。JVM是虚拟机&#xff0c;也是一种规范&#xff0c;他遵循…

python代码画皮卡丘_Python气象绘图实例我们一起画台风(代码+数据)

前段时间袭击中国的超强台风“利奇马”&#xff0c;以及这两天袭击美国的五级飓风“多利安”&#xff0c;让我们感受到了大自然的力量。所以&#xff0c;今天分享一个简单的Python实例&#xff0c;也算是延续前面python气象绘图系列(点击链接1&#xff1b;点击链接2)&#xff0…

Windows Socket编程笔记之最简单的小Demo

Windows Socket编程的大致过程:服务器端:----过程-------------对应的API------- 0.初始化 | WSAStartup() 1.创建Socket | socket() 2.绑定Socket | bind() 3.监听 | listen() 4.接受连接 | accept() 5.接收/发送数据 | recv()/send()…

React项目实战

一、环境搭建 1.安装react-cli脚手架&#xff08;保证提前安装好Node最新版本&#xff09; npm config set registry http://registry.npm.taobao.org/ npm config set sass-binary-site http://npm.taobao.org/mirrors/node-sass npm isntall -g create-react-app 2.查看react…

win7完美兼容DynamipsGUI(小凡模拟器)攻略

博主又是好久没写了&#xff0c;今天闲来无事与大家一起分享一下如何在windows7平台下完美兼容DynamipsGUI&#xff08;小凡模拟器&#xff09;的一个小窍门~ 对于学习cisco的朋友来说&#xff0c;DynamipsGUI&#xff08;小凡模拟器&#xff09;一定不陌生&#xff0c;在这就不…

使用PHPExcel 对表格进行,读取和写入的操作。。。。

下面的代码是使用PHPExcel 对多个表格数据进行读取&#xff0c; 然后整合的写入新的表格的方法&#xff01;&#xff01;&#xff01;代码有点粗糙 &#xff0c; 多多保函&#xff01;&#xff01;&#xff01; 这里有些地方注意下&#xff0c;如果你的表格数据过大&#xff0c…

c# .netframwork 4.0 调用 2.0时报错 混合模式程序集是针对“v2.0.50727”版的运行时生成的,在没有配置其他信息的情况下,无法在 4.0 运行时中加载该程序集。...

“System.IO.FileLoadException”类型的未经处理的异常在 XXX.dll 中发生 其他信息: 混合模式程序集是针对“v2.0.50727”版的运行时生成的&#xff0c;在没有配置其他信息的情况下&#xff0c;无法在 4.0 运行时中加载该程序集。 这时需要改dbconfig配置 在configuration 节点…

python多线程并发_Python进阶记录之基础篇(二十四)

回顾在Python进阶记录之基础篇(二十三)中&#xff0c;我们介绍了进程的基本概念以及Python中多进程的基本使用方法。其中&#xff0c;需要重点掌握多进程的创建方法、进程池和进程间的通信。今天我们讲一下Python中的多线程。线程的基本概念线程是操作系统能够进行运算调度的最…

awk处理文件内容格式

今天运营出了点问题&#xff0c;需要对特定时间段充值数做一个处理&#xff0c;文件格式有特定要求&#xff0c;要符合erlang的格式{roleID,gold}.mysql导出所有数据结果如下【取部分数据看】&#xff1a;kuwo 4 50004106230500 100kuwo 4 50004106230900 …

QQ远程协助没动静?QQ版本有讲究

一位网友觉得电脑反应速度慢了&#xff0c;想通过QQ远程协助让我处理一下。不料接受请求后&#xff0c;等了许久都显示网友电脑的桌面&#xff0c;而网友那边QQ也没有任何提示。 反复尝试了几次都是如此。 询问网友得知他用的QQ为2011版&#xff0c;而我使用的QQ是2008版。难…

java课堂测试样卷-----简易学籍管理系统

程序设计思路&#xff1a;分别建立两个类&#xff1a;ScoreInformation类(用来定义学生的基本信息以及设置set和get函数&#xff09;ScoreManagement类&#xff08;用来定义实现学生考试成绩录入&#xff0c;考试成绩修改&#xff0c;绩点计算等功能的函数&#xff09;和一个主…

python3安装setuptools步骤_setuptools、pip的安装

第2篇分享 安装setuptools 下载setuptools源码setuptools-25.2.0.tar.gz选择需要的版本 这是一个压缩文件&#xff0c;将其解压到桌面&#xff0c;并进入该文件夹 按住shift键后&#xff0c;在文件夹空白处点击鼠标右键&#xff0c;选择&#xff1a;在此处打开命令窗重点&#…

如何将简单CMS后台管理系统示例转换为Java、Php等不同后台语言的版本

等下要去坐车&#xff0c;今天就不继续唠叨开发过程了&#xff0c;来谈一下普遍比较关心的后台语言问题。学习Ext JS&#xff0c;笔者一直强调学习的中心思路是“界面与数据是分离”。只要好好掌握这个思路&#xff0c;深入了解Ext JS的运作过程&#xff0c;就不会为后台语言使…

[面试]future模式

Future模式 什么是future模式? 传统单线程环境下&#xff0c;调用函数是同步的&#xff0c;必须等待程序返回结果后&#xff0c;才可进行其他处理。 Futrue模式下&#xff0c;调用方式改为异步。 Futrue模式的核心在于&#xff1a;充分利用主函数中的等待时间&#xff0c;利用…

java ide

tidespringsource sts a vmware product plugin:Aptana Studio 3(集成了Git) Run on Jettyeclipse for jee plugin:JBoss Tools,m2eclipe,spirng tools,svn

成长秘笈:是你教我,不是我教你

郑昀 20180622 “谢谢你&#xff0c;你是第一个面试的时候跟我说这么详细的。那我到你们公司之后怎么就能成长了呢&#xff1f;” “你们这些人最大的问题是出不了方案。 为什么出不了方案&#xff1f; 因为没有养成深度思考问题的习惯。 实现方案、算法、数据迁移、准备数据、…

计算机网络面试题(一)

1、OSI&#xff0c;TCP/IP&#xff0c;五层协议的体系结构&#xff0c;以及各层协议 OSI分层 &#xff08;7层&#xff09;&#xff1a;物理层、数据链路层、网络层、传输层、会话层、表示层、应用层。 TCP/IP分层&#xff08;4层&#xff09;&#xff1a;网络接口 网络层、运…

Ubuntu下安装和配置Apache2

在Ubuntu中安装apache 安装指令&#xff1a;sudo apt-get install apache2 安装结束后&#xff1a; 产生的启动和停止文件是&#xff1a;/etc/init.d/apache2 启动&#xff1a;sudo apache2ctl -k start 停止&#xff1a;sudo apache2ctl -k stop 重新启动&#xff1a;sudo apa…

苹果电脑安装python3密码_mac系统安装Python3初体验

前沿 对于iOS开发不要随便拆卸系统自带的Python,因为有很多 library 还是使用 Python2.7。 1 安装Xcode 1.1 App Store 搜索Xcode 并安装 1.2 安装 Xcode command line tool 1.2.1 打开命令行terminal工具 control space 输入terminal 回车 1.2.2 安装Xcode command line tool…

【IBM Tivoli Identity Manager 学习文档】3 系统部署

作者&#xff1a;gnuhpc 出处&#xff1a;http://www.cnblogs.com/gnuhpc/ ITIM 5.0 单服务器配置和部署。 部署ITIM之前要对其组件进行部署&#xff1a; IBM DB2 Enterprise 9.1 with FP2 IBM WebSphere Application Server 6.1 with FP9 IBM Tivoli Directory Server 6.2 IB…

数据结构Java版之红黑树(八)

红黑树是一种自动平衡的二叉查找树&#xff0c;因为存在红黑规则&#xff0c;所以有效的防止了二叉树退化成了链表&#xff0c;且查找和删除的速度都很快&#xff0c;时间复杂度为log(n)。 什么是红黑规则&#xff1f; 1.根节点必须是黑色的。 2.节点颜色要么是红要么是黑。 3.…