day08运动函数封装
1.回顾
2.同步异步
-
同步:在做一件事的时候,如果这件事没有做完,后面的代码只能等待
-
for alert是同步
-
-
异步:在做一件事的时候,如果这件事需要等待,先去执行后面的代码,等时间到了再回来执行代码
-
定时器 ajax promise 事件绑定都是异步
-
<body> <script> // 同步 for (var i = 0; i < 100000; i++) { console.log(i); } console.log("结束了吗"); alert("提示信息")//阻塞性弹窗 console.log(2); //异步 console.log("开始"); setTimeout(function () { console.log(1); }, 0) console.log("结束"); // //事件绑定 console.log(1) btn.onclick = function () { console.log("3"); } console.log(2); </script>
3.小鸟起飞
3.1开始飞
-
需求:点击开始飞按钮 小鸟往右飞,飞到1000px的位置停止
-
==问题1:点击开始起飞 越点小鸟飞的越快==
-
分析:定时器累加的问题
-
解决:每次声明定时器之前 先清除原先的定时器
-
<body> <button>开始飞</button> <br> <img src="./img/right.gif" alt=""> <script> /* 问题1:点击开始起飞 越点越快 分析:定时器累加的问题 解决:每次声明定时器之前 先清除原先的定时器 */ var btn = document.getElementsByTagName("button"); var oImg = document.getElementsByTagName("img")[0]; var timer; //1.点击开始起飞 btn[0].onclick = function () { //建议:但凡是牵扯到元素移动的 建议使用定义偏移量(left right bottom top); //4.清除定时器 clearInterval(timer); //2.添加定时器 timer = setInterval(function () { //想在left值的基础上+10 如何获取left值 var current = parseInt(getStyle(oImg, "left")) + 10;//当前的left值 //3.运动到1000px停止 if (current >= 1000) { current = 1000; //清除定时器 clearInterval(timer); } oImg.style.left = current + "px"; }, 50) } </script> </body>
3.2来回飞
-
需求:点击凯旋按钮,小鸟往回飞
-
==问题2:点击凯旋的时候,越点小鸟飞的越快==
-
分析:定时器累加的问题
-
解决:在每次声明定时器的时候,都将原先的定时器清除
-
<body> <button>开始飞</button> <button>凯旋</button> <br> <img src="./img/right.gif" alt=""> <script> var btn = document.getElementsByTagName("button"); var oImg = document.getElementsByTagName("img")[0]; var timer; //1.点击开始起飞 btn[0].onclick = function () { //改变图片的路径 oImg.src = "./img/right.gif"; //4.清除定时器 clearInterval(timer); //2.添加定时器 timer = setInterval(function () { //想在left值的基础上+10 如何获取left值 var current = parseInt(getStyle(oImg, "left")) + 10;//当前的left值 //3.运动到1000px停止 if (current >= 1000) { current = 1000; //清除定时器 clearInterval(timer); } oImg.style.left = current + "px"; }, 50) } /* 问题2:点击凯旋的时候,越点小鸟飞的越开 分析:定时器累加的问题 解决:在每次声明定时器的时候,都将原先的定时器清除 */ // 5.凯旋 btn[1].onclick = function () { //改变图片的路径 oImg.src = "./img/left.gif"; // 8.清除定时器 clearInterval(timer); //6.添加定时器 timer = setInterval(function () { // 在当前left值的基础上-10 var current = parseInt(getStyle(oImg, "left")) - 10;//当前left值 // 7.运动到0px停止 if (current <= 0) { current = 0; clearInterval(timer); } oImg.style.left = current + "px"; }, 50) } </script>
3.3小鸟来回飞基础封装
-
封装的步骤
-
1.声明一个函数 把主要代码放入到函数中
-
2.找函数中可变的量作为参数 代入到函数中
-
3.调用
-
<body> <button>开始飞</button> <button>凯旋</button> <br> <img src="./img/right.gif" alt=""> <script> var btn = document.getElementsByTagName("button"); var oImg = document.getElementsByTagName("img")[0]; var timer; //1.点击开始起飞 btn[0].onclick = function () { //改变图片的路径 oImg.src = "./img/right.gif"; //4.清除定时器 clearInterval(timer); //2.添加定时器 timer = setInterval(function () { //想在left值的基础上+10 如何获取left值 var current = parseInt(getStyle(oImg, "left")) + 10;//当前的left值 //3.运动到1000px停止 if (current >= 1000) { current = 1000; //清除定时器 clearInterval(timer); } oImg.style.left = current + "px"; }, 50) } // 5.凯旋飞 btn[1].onclick = function () { //改变图片的路径 oImg.src = "./img/left.gif"; // 8.清除定时器 clearInterval(timer); //6.添加定时器 timer = setInterval(function () { // 在当前left值的基础上-10 var current = parseInt(getStyle(oImg, "left")) - 10;//当前left值 // 7.运动到0px停止 if (current <= 0) { current = 0; clearInterval(timer); } oImg.style.left = current + "px"; }, 50) } //运动函数封装 function move(elem, attr, step, target) { /* elem 运动的标签 attr是运动的样式 step步长 target目标值 */ //4.清除定时器 clearInterval(timer); //2.添加定时器 timer = setInterval(function () { //想在left值的基础上+10 如何获取left值 var current = parseInt(getStyle(elem, attr)) + step;//当前的left值 //3.运动到1000px停止 if (current >= target) { current = target; //清除定时器 clearInterval(timer); } elem.style[attr] = current + "px"; }, 50) } </script> </body>
3.4小鸟来回飞解决目标值
-
==问题3:点击开始飞 走的是判断条件1 凯旋飞 走的是判断条件2==
-
解决:开始飞 step >0 走开始飞的判断条件 凯旋飞 step<0 走结束飞的条件
-
<body> <button>开始飞</button> <button>凯旋</button> <br> <img src="./img/right.gif" alt=""> <script> var btn = document.getElementsByTagName("button"); var oImg = document.getElementsByTagName("img")[0]; var timer; //1.点击开始起飞 btn[0].onclick = function () { //改变图片的路径 oImg.src = "./img/right.gif"; move(oImg, "left", 10, 1000); } // 5.凯旋 btn[1].onclick = function () { //改变图片的路径 oImg.src = "./img/left.gif"; move(oImg, "left", -10, 0); } /* 问题3:点击开始飞 走的是判断条件1 凯旋飞 走的是判断条件2 解决:开始飞 step >0 凯旋飞 step<0 */ //运动函数封装 function move(elem, attr, step, target) { /* elem 运动的标签 attr是运动的样式 step步长 target目标值 */ //4.清除定时器 clearInterval(timer); //2.添加定时器 timer = setInterval(function () { //想在left值的基础上+10 如何获取left值 var current = parseInt(getStyle(elem, attr)) + step;//当前的left值 /* if (step > 0) { //开始飞的判断条件 条件1 //3.运动到1000px停止 if (current >= target) { current = target; //清除定时器 clearInterval(timer); } } else if (step < 0) { // 凯旋飞的判断条件 条件2 // 7.运动到0px停止 if (current <= target) { current = target; clearInterval(timer); } } */ // 改写条件1 /* if (step > 0 && current >= target) { current = target; //清除定时器 clearInterval(timer); } else if (step < 0 && current <= target) { current = target; clearInterval(timer); } */ //改写条件2 if ((step > 0 && current >= target) || (step < 0 && current <= target)) { current = target; clearInterval(timer); } elem.style[attr] = current + "px"; }, 50) } </script> </body>
3.5小鸟来回飞完善
-
==问题4:无论是开始飞还是结束飞 不考虑step的正负数问题==
分析: 开始飞 当前left值(current) 目标值(target) 0 < 1000 +step 凯旋飞 当前left值(current) 目标值(target) 1000 > 0 -step 判断条件:current < target ? +step :-step
<body> <button>开始飞</button> <button>凯旋</button> <br> <img src="./img/right.gif" alt=""> <script> var btn = document.getElementsByTagName("button"); var oImg = document.getElementsByTagName("img")[0]; var timer; //1.点击开始起飞 btn[0].onclick = function () { //改变图片的路径 oImg.src = "./img/right.gif"; move(oImg, "left", 10, 1000); } // 5.凯旋 btn[1].onclick = function () { //改变图片的路径 oImg.src = "./img/left.gif"; move(oImg, "left", 10, 0); } //运动函数封装 function move(elem, attr, step, target) { /* elem 运动的标签 attr是运动的样式 step步长 target目标值 */ // 判断step的正负数 step = parseInt(getStyle(elem, attr)) < target ? +step : -step; //4.清除定时器 clearInterval(timer); //2.添加定时器 timer = setInterval(function () { //想在left值的基础上+10 如何获取left值 var current = parseInt(getStyle(elem, attr)) + step;//当前的left值 // 走哪个判断条件 if ((step > 0 && current >= target) || (step < 0 && current <= target)) { current = target; clearInterval(timer); } elem.style[attr] = current + "px"; }, 50) } </script> </body>
3.6将运动函数封装到公共js文件
-
common.js
/* @author:朱银娟 @作用:运动函数封装 @params:elem 标签 @params:attr 样式名 string类型 @params:step 步长 number类型 @params:target 目标值 number类型 */ function move(elem, attr, step, target) { // 判断step的正负数 step = parseInt(getStyle(elem, attr)) < target ? +step : -step; //4.清除定时器 clearInterval(elem.timer); //2.添加定时器 elem.timer = setInterval(function () { //想在left值的基础上+10 如何获取left值 var current = parseInt(getStyle(elem, attr)) + step;//当前的left值 // 走哪个判断条件 if ((step > 0 && current >= target) || (step < 0 && current <= target)) { current = target; clearInterval(elem.timer); } elem.style[attr] = current + "px"; }, 50) }
-
页面使用
<body> <div></div> <script> // 让div的100px-500px console.log(move); var oDiv = document.getElementsByTagName("div")[0]; move(oDiv, "width", 10, 500); // 让div的500px-100px move(oDiv, "width", 10, 100); </script> </body>
4.轮播图效果
4.1轮播图布局
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <script src="./common.js"></script> <style> * { margin: 0; padding: 0; list-style: none; } .box { width: 800px; height: 400px; border: 3px solid red; margin: 0 auto; position: relative; overflow: hidden; } ul { width: 4000px; position: absolute; left: 0px; } li { width: 800px; height: 400px; float: left; } li img { width: 100%; height: 100%; } button { width: 80px; height: 30px; position: absolute; top: 50%; margin-top: -15px; } button:nth-of-type(1) { left: 0; } button:nth-of-type(2) { right: 0; } .dots { position: absolute; bottom: 0; left: 0; width: 100%; text-align: center; } .dots span { display: inline-block; width: 30px; height: 30px; border-radius: 50%; background-color: #fff; } </style> </head> <body> <!-- 可视区域 是一张图片的大小 --> <div class="box"> <!-- 图片列表 --> <ul> <li> <img src="./img/1.jpg" alt=""> </li> <li> <img src="./img/2.jpg" alt=""> </li> <li> <img src="./img/3.jpg" alt=""> </li> <li> <img src="./img/4.jpg" alt=""> </li> <li> <img src="./img/1.jpg" alt=""> </li> </ul> <!-- 左右箭头 --> <button><</button> <button>></button> <div class="dots"> <span style="background-color: red;"></span> <span></span> <span></span> <span></span> </div> </div> </body> </html>
4.2轮播图交互
<script> var oUl = document.getElementsByTagName("ul")[0];//图片列表 var btn = document.getElementsByTagName("button");//左右箭头 var oSpan = document.getElementsByTagName("span");//圆形指示点 var oBox = document.getElementsByClassName("box")[0]; var n = 0; // 1.自动轮播 每隔2s显示下一张 function auto() { //1张 -800*0 2张-800*1 3张-800*2 4张-800*3 5张(其实是第一张) -800*4 n++; if (n > 4) { // 衔接播放 oUl.style.left = "0px"; n = 1; } move(oUl, "left", 100, n * -800); //改变指示点 console.log(n); //排他:先将所有的span颜色都清空 for (var j = 0; j < oSpan.length; j++) { oSpan[j].style.backgroundColor = ""; } //当n==4的时候 虽然是第5张图片 其实显示的是第1张图片 if (n == 4) { oSpan[0].style.backgroundColor = "red"; } else { oSpan[n].style.backgroundColor = "red"; } } var timer = setInterval(auto, 2000); // 2.移入移出 停止和开启定时器 oBox.onmouseover = function () { clearInterval(timer); } oBox.onmouseout = function () { timer = setInterval(auto, 2000) } // 3.点击上一张 和下一张 btn[1].onclick = function () { //这里做的事和auto函数是一样的 auto(); } btn[0].onclick = function () { n--; if (n < 0) { // 快速将图片列表定位到-3200px的位置 oUl.style.left = "-3200px"; n = 3; } move(oUl, "left", 100, n * -800); // 改变指示点 // 排他:先清空所有span的样式 for (var j = 0; j < oSpan.length; j++) { oSpan[j].style.backgroundColor = ""; } //当n==4的时候 虽然是第5张图片 其实显示的是第1张图片 if (n == 4) { oSpan[0].style.backgroundColor = "red"; } else { oSpan[n].style.backgroundColor = "red"; } } // 4.点击小圆点 for (var i = 0; i < oSpan.length; i++) { oSpan[i].index = i; // 自定义索引 oSpan[i].onclick = function () { //ospan[0] 第一张图片n=0 ospan[1] 第二张n=1 // 在循环的点击事件如何拿到下标值 console.log(this.index); n = this.index; move(oUl, "left", 100, n * -800); // 改变指示点 for (var j = 0; j < oSpan.length; j++) { oSpan[j].style.backgroundColor = ""; } if (n == 4) { oSpan[0].style.backgroundColor = "red"; } else { oSpan[n].style.backgroundColor = "red"; } } } </script>
4.3轮播图封装
<script> var oUl = document.getElementsByTagName("ul")[0];//图片列表 var btn = document.getElementsByTagName("button");//左右箭头 var oSpan = document.getElementsByTagName("span");//圆形指示点 var oBox = document.getElementsByClassName("box")[0]; var n = 0; // 1.自动轮播 每隔2s显示下一张 function auto() { //1张 -800*0 2张-800*1 3张-800*2 4张-800*3 5张(其实是第一张) -800*4 n++; if (n > 4) { // 衔接播放 oUl.style.left = "0px"; n = 1; } change(); } var timer = setInterval(auto, 2000); // 2.移入移出 停止和开启定时器 oBox.onmouseover = function () { clearInterval(timer); } oBox.onmouseout = function () { timer = setInterval(auto, 2000) } // 3.点击上一张 和下一张 btn[1].onclick = function () { //这里做的事和auto函数是一样的 auto(); } btn[0].onclick = function () { n--; if (n < 0) { // 快速将图片列表定位到-3200px的位置 oUl.style.left = "-3200px"; n = 3; } change(); } // 4.点击小圆点 for (var i = 0; i < oSpan.length; i++) { oSpan[i].index = i; // 自定义索引 oSpan[i].onclick = function () { //ospan[0] 第一张图片n=0 ospan[1] 第二张n=1 // 在循环的点击事件如何拿到下标值 console.log(this.index); n = this.index; change(); } } function change() { move(oUl, "left", 100, n * -800); // 改变指示点 for (var j = 0; j < oSpan.length; j++) { oSpan[j].style.backgroundColor = ""; } if (n == 4) { oSpan[0].style.backgroundColor = "red"; } else { oSpan[n].style.backgroundColor = "red"; } } </script>
5.js的对象
-
对象: 在JS中万物皆对象,可以将对象分为“内部对象”、“宿主对象”和“自定义对象”三种。
-
本地对象「内部对象」:JS中的内部对象包括Array、Boolean、Date、Function、Global、 Math、Number、Object、RegExp、String,Error对象, 其中Global和Math这两个对象又被称为“内置对象”,这两个对象在脚本程序初始化时被创建,不必实例化这两个对象。
-
宿主对象:宿主对象就是执行JS脚本的环境提供的对象,就是浏览器提供的对象,如window和document
-
自定义对象
-
-
api
-
API,全称Application Programming Interface,即应用程序编程接口。说白了就是函数,但是这些函数都是封装好的,固定功能的,可以直接调用实现功能的。 例如遥控器,不同的按键不同的功能,都是提前定义好的
-
6.Math对象
-
Math对象和Global对象不需要创建就可以使用
6.1取整
-
parseInt() 强制转为Number类型 从左往右开始转换,遇到不能转换的或者末尾结束,如果一开始就不能转换,结果则是NaN 结果取整(直接舍弃小数)
-
Math.floor() 向下取整 舍弃小数部分
-
Math.ceil() 向上取整 有小数就进位
-
Math.round() 四舍五入
//1.取整 //parseInt() 强制转为Number类型 从左往右开始转换,遇到不能转换的或者末尾结束,如果一开始就不能转换,结果则是NaN 结果取整(直接舍弃小数) console.log(parseInt("10.5px"));//10 // Math.floor() 向下取整 舍弃小数部分 console.log(Math.floor("3.999999"));//3 console.log(Math.floor("3.000001"));//3 // Math.ceil() 向上取整 有小数就进位 console.log(Math.ceil("3.999999"));//4 console.log(Math.ceil("3.000001"));//4 console.log(Math.ceil("3.00000"));//3 // Math.round() 四舍五入 console.log(Math.round("3.999999"));//4 console.log(Math.round("3.000001"));//3
6.2数学方法
-
Math.max(数值1,数值2,数值3......) 找序列中最大的值
-
Math.min(数值1,数值2,数值3......) 找序列中最小的值
-
Math.abs() 取绝对值
-
Math.sqrt() 开根号
-
Math.pow(基数,次方幂)
// 2.Math中的数学方法 // Math.max(数值1,数值2,数值3......) 找序列中最大的值 console.log(Math.max(1, 2, 3, 4, 5));//5 // Math.min(数值1,数值2,数值3......) 找序列中最小的值 console.log(Math.min(1, 2, 3, 4, 5));//1 // Math.abs() 取绝对值 console.log(Math.abs(-10));//10 // Math.sqrt() 开根号 console.log(Math.sqrt(9));//3 // Math.pow(基数,次方幂) console.log(Math.pow(2, 10));//1024 console.log(Math.pow(10, 2));//100
7.面试题
什么是同步和异步 js的对象分类