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="data:images1/01.jpg"></li><li><img src="data:images1/02.jpg"></li><li><img src="data:images1/03.jpg"></li><li><img src="data:images1/04.jpg"></li><li><img src="data: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="data:images2/1.jpg"></li><li><img src="data:images2/2.jpg"></li><li><img src="data:images2/3.jpg"></li><li><img src="data:images2/4.jpg"></li><li><img src="data: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="data:images3/1.jpg"></li><li><img src="data:images3/2.jpg"></li><li><img src="data:images3/3.jpg"></li><li><img src="data:images3/4.jpg"></li><li><img src="data:images3/5.jpg"></li><li><img src="data: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

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

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

    1.client家族 ◆box.clientWidth:表示盒子的宽度加padding ◆box.clientHeight:表示盒子的高度加padding ◆box.clientTop:表示盒子上边的 ...

  2. 【web前端特效源码】使用HTML5+CSS3+JavaScript制作一个可拖动的拼图游戏动画效果~适合初学者~超简单~ |it前端开发

    b站视频演示效果: [web前端特效源码]使用HTML5+CSS3+JavaScript制作一个可拖动的拼图游戏动画效果~适合初学者~超简单~ |前端开发|IT软件 效果图: 完整代码: <!D ...

  3. javaScript中三大家族总结

    三大家族整体解释图 第一大家族:offset家族 offset 是自己的-- 目的: 方便的获取元素尺寸 offsetWidth offsetHeight 得到对象的宽度和高度(自己的,与他人无关) ...

  4. JavaScript之jQuery够用即可(事件委托、动画效果、扩展插件)

    文章目录 一.事件委托 二.JS的动画效果 三.扩展插件 一.事件委托 1.事件委托 其实就是给对象绑定一个事件,但是委托给它所属的每一个子对象了,因此每一个子对象都具有添加进的功能 书写格式如下: ...

  5. javascript实现鼠标移动两个小人的动画效果

    动画效果 效果说明:鼠标按住其中一个小人拖动,可以实现屏幕上两个小人的移动 实现 1.HTML中的代码 <div class="background" @mousemove= ...

  6. JavaScript网页特效-浮现社会主义核心价值观文字动画效果

    1.案例呈现 用户在页面单击鼠标左键,页面浮现"富强"."民主"."文明"."和谐"."自由".&q ...

  7. HTML5+CSS3+JavaScript 实现按键令小女孩移动,改变动画效果

    素材图片 1.将小女孩图片截出来,在浏览器中居中显示,一个小女孩是96px <body><div class="box"></div> < ...

  8. 常用jquery鼠标事件和渐变动画效果

    2019独角兽企业重金招聘Python工程师标准>>> 鼠标事件是在用户移动鼠标光标或者使用任意鼠标键点击时触发的以下是具体事件的介绍: (1):click事件:click事件于用户 ...

  9. Javascript中交换两个变量值的十种方法相关笔记(一)

    交换两个变量的值十种方法: ◆第1.6.7.8.10既可以交换简单数据类型也可以交换复杂数据类型的,基本可以确定是任何类型的值. ◆第2,3,4,5,9只可以交换简单数据类型的,基本可以确定是数字类型 ...

最新文章

  1. 王贻芳院士:为什么中国要探究中微子实验?
  2. python+opencv用电脑调用手机摄像头或其他网路摄像头
  3. CentOS6.x下GitLab安装
  4. c语言分量的运算符,C语言基础(04-运算符和表达式)
  5. Android4.4 Sensor APP--HAL代码流程
  6. 在Openstack上创建并访问Kubernetes集群
  7. Android【报错】Description Resource Path Location Type Unparsed aapt error(s)! Cheheck the console for o
  8. 严蔚敏数据结构c语言版第二版思维导图
  9. js验证身份证营业执照组织机构代码等
  10. 苹果HomeKit、小米、谷歌HomeKit等智能家居系统,哪一款适合你?【智能家居评测】
  11. STM32F072 NUCLEO笔记1-驱动安装以及第一个工程(mbed版)
  12. vhdl8三种方式实现38译码器
  13. 【unity】解决3d max导出的fbx在unity贴图丢失的问题
  14. 相信美好就能遇见美好—西安独行三日短途穷游 攻略
  15. 纯H5实现扫码:浏览器扫码
  16. 各互联网技术领域pdf图书合集(百度网盘)
  17. windows资源管理器对文件右键未响应!电脑小白求救[哭唧唧]!!!
  18. HTML配色工具!在线配色工具
  19. 计算机二级ms真题及答案网盘,全国计算机二级MS Office考试真题及答案
  20. XML(3)XDocument与XmlDocument递归读取xml文件

热门文章

  1. CCNA CCNP CCIE所有实验名称完整版
  2. 影著协公布的使用费收取标准
  3. ASP.NET自定义控件组件开发 第四章 组合控件开发CompositeControl
  4. 创建react应用程序_通过创建食谱应用程序来学习在React中使用API
  5. 以太坊公链私链_如何使用以太坊构建汽车制造供应链系统
  6. Spring servlet
  7. oracle重建实例_记一次误删Oracle控制文件并恢复过程
  8. 冒泡排序_python实现冒泡排序
  9. 学java培训开发需要多少钱
  10. leetcode--删除排序数组中的重复项--python