首页 > 代码库 > JS-特效 ~ 01. 事件对象、offset偏移/检测、无缝滚动、自动循环轮播图
JS-特效 ~ 01. 事件对象、offset偏移/检测、无缝滚动、自动循环轮播图
Math.round ( ) :正书四舍五入,负数五舍六入
用定时器,先清除定时器
事件对象 event
event:事件被触动时,鼠标和键盘的状态,通过属性控制
Offset:偏移,检测
1. 获取元素尺寸
2. 检测盒子的宽高
事件源.offsetLeft. /. ele.offsetWidth /返回的数值没有单位,是number类型 /包括内边距、边框,不包括外边距
3. 获取定位的元素的left和top值 offsetLeft / offsetTop
如果被获取的元素没有定位,则按照浏览器为基准/从父盒子的padding开始计算
返回最近距离上级盒子,定位的左上位置/父盒子的边框不算/ ele.style.left 自带px
4. offsetParent 若有除static之外的定位,则返回最近的
检测父盒子中带有定位的父盒子节点/返回上级已定位盒子的标签/若父系盒子没有定位,则返回body
5. offsetLeft和style.left的区别
ele.style.left带有px 是字符串类型. / offsetLefta不带px,是数值类型
.style.top 可获取行内式,若内有top属性,返回 ‘ ‘ ;空字符串
offsetLeft可返回没有定位的盒子,没定位返回body
offsetLeft只读, .style.top可读写赋值
animate. 动画
1. 闪现/匀速/缓动
2. 匀速: 添加定时循环事件。盒子原来的长度加上步长/用offsetLeft取值 ,.style.left 幅值
无缝滚动思路
思路: 复制第一张图片放到ul最后/当图片到最后一张时,此时为复制第一张图,此时若继续,则先瞬移到第一张本图,
然后照常轮播
步骤
- 获取事件源以及相关元素
- 复制第一张图片所在的li添加到ul最后
- 给ol中添加li,ul个数见一个,并点亮第一个
- 鼠标放到ol的li上切换图片
- 添加定时器
- 左右切换图片
<!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8"> <title></title> <style> div { width: 100px; height: 100px; background-color: pink; position: absolute; } </style> </head> <body> <button>动画</button> <div class="box" style="left: 0px"></div> <script> var btn = document.getElementsByTagName("button")[0]; var div = document.getElementsByTagName("div")[0]; //闪动 // btn.onclick = function () { // div.style.left = "500px"; // } //匀速运动 btn.onclick = function () { //定时器,每隔一定的时间向右走一些 setInterval(function () { console.log(parseInt(div.style.left)); // div.style.left = parseInt(div.style.left)+10+"px"; //NaN不能用 //动画原理: 盒子未来的位置 = 盒子现在的位置 + 步长; //style.left赋值,用offsetLeft获取值。 //style.left获取值不方便,获取行内式,如果没有事“”;容易出现NaN; //offsetLeft获取值特别方便,而且是现成number方便计算。因为他是只读的不能赋值。 div.style.left = div.offsetLeft + 10 + "px"; },300); } </script> </body> </html>
<!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8"> <title></title> <style> .box1 { margin: 0; padding: 5px; height: 300px; background-color: #ddd; position: relative; } button { margin: 5px; } .box2 { width: 100px; height: 100px; background-color: red; position: absolute; left: 0; top: 40px; } .box3 { width: 100px; height: 100px; background-color: yellow; position: absolute; left: 0; top: 150px; } </style> </head> <body> <div class="box1"> <button>运动到200</button> <button>运动到400</button> <div class="box2"></div> <div class="box3"></div> </div> <script> var btnArr = document.getElementsByTagName("button"); var box2 = document.getElementsByClassName("box2")[0]; var box3 = document.getElementsByClassName("box3")[0]; //绑定事件 btnArr[0].onclick = function () { //如果有一天我们要传递另外一个盒子,那么我们的方法就不好用了 //所以我们要增加第二个参数,被移动的盒子本身。 animate(box2,200); animate(box3,200); } btnArr[1].onclick = function () { animate(box2,400); animate(box3,400); } function animate(ele,target){ //要用定时器,先清除定时器 //一个盒子只能有一个定时器,这样儿的话,不会和其他盒子出现定时器冲突 //而定时器本身讲成为盒子的一个属性 clearInterval(ele.timer); //我们要求盒子既能向前又能向后,那么我们的步长就得有正有负 //目标值如果大于当前值取正,目标值如果小于当前值取负 var speed = target>ele.offsetLeft?10:-10; ele.timer = setInterval(function () { //在执行之前就获取当前值和目标值之差 var val = target - ele.offsetLeft; ele.style.left = ele.offsetLeft + speed + "px"; //目标值和当前值只差如果小于步长,那么就不能在前进了 //因为步长有正有负,所有转换成绝对值来比较 if(Math.abs(val)<Math.abs(speed)){ ele.style.left = target + "px"; clearInterval(ele.timer); } },30) } </script> </body> </html>
<!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8"> <title></title> <style> * { margin: 0; padding: 0; } .box { width: 490px; height: 170px; padding: 5px; border: 1px solid #ccc; margin: 100px auto; } .inner { width: 490px; height: 170px; position: relative; overflow: hidden; } ul { width: 500%; list-style: none; position: absolute; left: 0; } li { float: left; } .square { position: absolute; bottom: 10px; right: 10px; } span { display: inline-block; width: 16px; height: 16px; background-color: #fff; text-align: center; margin: 3px; border: 1px solid #ccc; line-height: 16px; cursor: pointer; } .current { background-color: darkorange; color: #fff; } </style> <script> window.onload = function () { //需求:鼠标放到小方块上面,上面的图片(ul向左移动指定的个数个图片的宽) //思路:绑定事件,点亮指定的盒子,移动ul。 //步骤: //1.获取事件源和相关元素 //2.绑定事件和书写事件驱动程序(for循环绑定) //3.点亮盒子 //4.移动ul(向左移动,给定目标为-值,放到第n个小方块上向左移动n-1个图片的宽) //1.获取事件源和相关元素 var inner = document.getElementById("inner"); var imgWidth = inner.offsetWidth; var ul = inner.children[0]; var spanArr = inner.children[1].children; //2.绑定事件和书写事件驱动程序(for循环绑定) for(var i=0;i<spanArr.length;i++){ //属性绑定(自定义属性参数盒子的索引值) //用span的innerHTML属性也可以,但是为了代码的健壮性,我们选择使用自己的属性 spanArr[i].index = i; //绑定的是索引值,所以移动盒子的时候不用-1 spanArr[i].onmouseover = function () { //3.点亮盒子 //排他思想 for(var j=0;j<spanArr.length;j++){ spanArr[j].className = ""; } this.className = "current"; //4.移动ul(向左移动,给定目标为-值,放到第n个小方块上向左移动n-1个图片的宽) //利用框架移动盒子。(两个参数:1.元素。 2.目标位置) animate(ul,-this.index*imgWidth); } } function animate(ele,target){ clearInterval(ele.timer); var speed = target>ele.offsetLeft?10:-10; ele.timer = setInterval(function () { var val = target - ele.offsetLeft; ele.style.left = ele.offsetLeft + speed + "px"; if(Math.abs(val)<Math.abs(speed)){ ele.style.left = target + "px"; clearInterval(ele.timer); } },10) } } </script> </head> <body> <div class="box"> <div class="inner" id="inner"> <ul> <li><img src="http://www.mamicode.com/images/01.jpg" /></li> <li><img src="http://www.mamicode.com/images/02.jpg" /></li> <li><img src="http://www.mamicode.com/images/03.jpg" /></li> <li><img src="http://www.mamicode.com/images/04.jpg" /></li> <li><img src="http://www.mamicode.com/images/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> </body> </html>
<!doctype html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>无标题文档</title> <style type="text/css"> body,ul,ol,li,img{margin:0;padding:0;list-style:none;} #box{width:490px;height:170px;padding:5px; position: relative;border:1px solid #ccc;margin:100px auto 0;overflow:hidden;} .ad{width:490px;height:170px;overflow:hidden;position:relative;} #box img{width:490px;} .ad ol{position:absolute;right:10px;bottom:10px;} .ad ol li{width:20px;height:20px;line-height:20px;border:1px solid #ccc;text-align:center;background:#fff;float:left;margin-right:10px;cursor:pointer;_display:inline;} .ad ol li.current{background:yellow;} .ad ul li{float:left;} .ad ul{ position:absolute; top:0; width:2940px;} .ad ul li.current{display:block;} #arr {display: none;} #arr span{ width:40px; height:40px; position:absolute; left:5px; top:50%; margin-top:-20px; background:#000; cursor:pointer; line-height:40px; text-align:center; font-weight:bold; font-family:‘黑体‘; font-size:30px; color:#fff; opacity:0.3; border:1px solid #fff;} #arr #right{right:5px; left:auto;} </style> </head> <body> <div id="box" class="all"> <div class="ad"> <ul id="imgs"> <li><img src="http://www.mamicode.com/images/1.jpg" /></li> <li><img src="http://www.mamicode.com/images/2.jpg" /></li> <li><img src="http://www.mamicode.com/images/3.jpg" /></li> <li><img src="http://www.mamicode.com/images/4.jpg" /></li> <li><img src="http://www.mamicode.com/images/5.jpg" /></li> </ul> </div> <div id="arr"> <span id="left"><</span> <span id="right">></span> </div> </div> <script> //需求:鼠标放到盒子上,显示左右切换的图片。点击左则按钮图片(ul)向右移动,相反的按钮向左移动。 //思路:获取两个按钮,点击左侧按钮移动ul向右走(每次只走一张)(计数器从0开始)。 //如何移动盒子。利用计数器模拟index值,点右侧自增,点左侧自减。 //步骤: //1.鼠标放上去显示移开以藏 //2.点击右侧盒子图片向做移动并用计数器模拟index值。 //3,点击左侧盒子,同理。 //1.鼠标放上去显示移开以藏 var box = document.getElementById("box"); var imgWidth = box.children[0].offsetWidth; var ul = box.children[0].children[0]; var boxLeftRight = box.children[1]; var btnArr = boxLeftRight.children; //鼠标放上去显示,移开隐藏 box.onmouseover = function () { boxLeftRight.style.display = "block"; } box.onmouseout = function () { boxLeftRight.style.display = "none"; } //2.点击右侧盒子图片向做移动并用计数器模拟index值。 //定义计数器 var index = 0; btnArr[1].onclick = function () { index++; //我们要对index的值进行约束。index的值必须在[0,4] if(index>ul.children.length-1){ index = ul.children.length-1; alert("到头了!"); } //点击盒子以后移动图片(ul,和目标位置) animate(ul,-index*imgWidth); } //3,点击左侧盒子,同理。 btnArr[0].onclick = function () { index--; if(index<0){ index = 0; alert("第一张!"); } //点击盒子以后移动图片(ul,和目标位置) animate(ul,-index*imgWidth); } function animate(ele,target){ clearInterval(ele.timer); var speed = target>ele.offsetLeft?10:-10; ele.timer = setInterval(function () { var val = target - ele.offsetLeft; ele.style.left = ele.offsetLeft + speed + "px"; if(Math.abs(val)<Math.abs(speed)){ ele.style.left = target + "px"; clearInterval(ele.timer); } },10) } </script> </body> </html>
<!doctype html> <html lang="en"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> <title>无标题文档</title> <style type="text/css"> * { padding: 0; margin: 0; list-style: none; border: 0; } .all { width: 500px; height: 200px; padding: 7px; border: 1px solid #ccc; margin: 100px auto; position: relative; } .screen { width: 500px; height: 200px; overflow: hidden; position: relative; } .screen li { width: 500px; height: 200px; overflow: hidden; float: left; } .screen ul { position: absolute; left: 0; top: 0px; width: 3000px; } .all ol { position: absolute; right: 10px; bottom: 10px; line-height: 20px; text-align: center; } .all ol li { float: left; width: 20px; height: 20px; background: #fff; border: 1px solid #ccc; margin-left: 10px; cursor: pointer; } .all ol li.current { background: yellow; } #arr { display: none; } #arr span { width: 40px; height: 40px; position: absolute; left: 5px; top: 50%; margin-top: -20px; background: #000; cursor: pointer; line-height: 40px; text-align: center; font-weight: bold; font-family: ‘黑体‘; font-size: 30px; color: #fff; opacity: 0.3; border: 1px solid #fff; } #arr #right { right: 5px; left: auto; } </style> <script> window.onload = function () { //需求:无缝滚动。 //思路:赋值第一张图片放到ul的最后,然后当图片切换到第五张的时候 // 直接切换第六章,再次从第一张切换到第二张的时候先瞬间切换到 // 第一张图片,然后滑动到第二张 //步骤: //1.获取事件源及相关元素。(老三步) //2.复制第一张图片所在的li,添加到ul的最后面。 //3.给ol中添加li,ul中的个数-1个,并点亮第一个按钮。 //4.鼠标放到ol的li上切换图片 //5.添加定时器 //6.左右切换图片(鼠标放上去隐藏,移开显示) //1.获取事件源及相关元素。(老三步) var all = document.getElementById("all"); var screen = all.firstElementChild || all.firstChild; var imgWidth = screen.offsetWidth; var ul = screen.firstElementChild || screen.firstChild; var ol = screen.children[1]; var div = screen.lastElementChild || screen.lastChild; var spanArr = div.children; console.log(all); console.log(screen); console.log(imgWidth); console.log(ul); console.log(ol); console.log(div); console.log(spanArr); //2.复制第一张图片所在的li,添加到ul的最后面。 var ulNewLi = ul.children[0].cloneNode(true); ul.appendChild(ulNewLi); //3.给ol中添加li,ul中的个数-1个,并点亮第一个按钮。 for (var i = 0; i < ul.children.length - 1; i++) { var olNewLi = document.createElement("li"); olNewLi.innerHTML = i + 1; ol.appendChild(olNewLi) } var olLiArr = ol.children; olLiArr[0].className = "current"; //4.鼠标放到ol的li上切换图片 for (var i = 0; i < olLiArr.length; i++) { //自定义属性,把索引值绑定到元素的index属性上 olLiArr[i].index = i; olLiArr[i].onmouseover = function () { //排他思想 for (var j = 0; j < olLiArr.length; j++) { olLiArr[j].className = ""; } this.className = "current"; //鼠标放到小的方块上的时候索引值和key以及square同步 // key = this.index; // square = this.index; key = square = this.index; //移动盒子 animate(ul, -this.index * imgWidth); } } //5.添加定时器 var timer = setInterval(autoPlay, 1000); //固定向右切换图片 //两个定时器(一个记录图片,一个记录小方块) var key = 0; var square = 0; function autoPlay() { //通过控制key的自增来模拟图片的索引值,然后移动ul key++; if (key > olLiArr.length) { //图片已经滑动到最后一张,接下来,跳转到第一张,然后在滑动到第二张 ul.style.left = 0; key = 1; } animate(ul, -key * imgWidth); //通过控制square的自增来模拟小方块的索引值,然后点亮盒子 //排他思想做小方块 square++; if (square > olLiArr.length - 1) {//索引值不能大于等于5,如果等于5,立刻变为0; square = 0; } for (var i = 0; i < olLiArr.length; i++) { olLiArr[i].className = ""; } olLiArr[square].className = "current"; } //鼠标放上去清除定时器,移开后在开启定时器 all.onmouseover = function () { div.style.display = "block"; clearInterval(timer); } all.onmouseout = function () { div.style.display = "none"; timer = setInterval(autoPlay, 1000); } //6.左右切换图片(鼠标放上去显示,移开隐藏) spanArr[0].onclick = function () { //通过控制key的自增来模拟图片的索引值,然后移动ul key--; if (key < 0) { //先移动到最后一张,然后key的值取之前一张的索引值,然后在向前移动 ul.style.left = -imgWidth * (olLiArr.length) + "px"; key = olLiArr.length - 1; } animate(ul, -key * imgWidth); //通过控制square的自增来模拟小方块的索引值,然后点亮盒子 //排他思想做小方块 square--; if (square < 0) {//索引值不能大于等于5,如果等于5,立刻变为0; square = olLiArr.length - 1; } for (var i = 0; i < olLiArr.length; i++) { olLiArr[i].className = ""; } olLiArr[square].className = "current"; } spanArr[1].onclick = function () { //右侧的和定时器一模一样 autoPlay(); } function animate(ele, target) { clearInterval(ele.timer); var speed = target > ele.offsetLeft ? 10 : -10; ele.timer = setInterval(function () { var val = target - ele.offsetLeft; ele.style.left = ele.offsetLeft + speed + "px"; if (Math.abs(val) < Math.abs(speed)) { ele.style.left = target + "px"; clearInterval(ele.timer); } }, 10) } } </script> </head> <body> <div class="all" id=‘all‘> <div class="screen" id="screen"> <ul id="ul"> <li><img src="http://www.mamicode.com/images/1.jpg" width="500" height="200"/></li> <li><img src="http://www.mamicode.com/images/2.jpg" width="500" height="200"/></li> <li><img src="http://www.mamicode.com/images/3.jpg" width="500" height="200"/></li> <li><img src="http://www.mamicode.com/images/4.jpg" width="500" height="200"/></li> <li><img src="http://www.mamicode.com/images/5.jpg" width="500" height="200"/></li> </ul> <ol> </ol> <div id="arr"> <span id="left"><</span> <span id="right">></span> </div> </div> </div> </body> </html>
JS-特效 ~ 01. 事件对象、offset偏移/检测、无缝滚动、自动循环轮播图