ThinkChat2.0新版上线,更智能更精彩,支持会话、画图、阅读、搜索等,送10W Token,即刻开启你的AI之旅 广告
## 动画(熟悉) ### 让每一个元素记录一个定时器 在上一节的学习中,我们将动画封装到了一个animate函数中。这种封装动画的方式存在一个存在一个问题,即此时的animate函数只能针对一个元素开启一个定时器来执行动画,如果想在页面中同时让多个div的运动起来,做不到!此时我们就需要改进animate函数了。那如何才能让也个页面中的多个元素同时运动起来呢? 现在的animate做不到让多个元素同时运动,是因为我们的timeId是共享的,假如每个元素能存储自己的timeId,这个问题就能解决了。让元素存储timeId其实就是将timeId存储到元素的属性中,所以我们可修改代码为如下。 **需求:**让每一个元素记录一个定时器; html和css代码 ~~~ <style>        #box {            position: relative;            background-color: red;            width: 100px;            height: 100px;       }        #box2 {            position: relative;            background-color: blue;            width: 100px;            height: 100px;       }    </style> ​ <input type="button" value="移动400" id="btn"> <input type="button" value="移动800" id="btn2"> <div id="box"></div> <div id="box2"></div> ~~~ JavaScript代码 ~~~ //需求:让每一个元素记录一个定时器 ​ var btn = document.getElementById('btn'); var btn2 = document.getElementById('btn2'); var box = document.getElementById('box'); var box2 = document.getElementById('box2'); ​ // 1、点击按钮,div向右移动 btn.onclick = function () {    animate(box, 400, 10); } ​ btn2.onclick = function () {    animate(box2, 800, 3); } ​ // var timeId = null; //封装动画代码到函数中 function animate(element, target, frequency){    //判断当前文档中是否已经启用定时器,如果启用,则先销毁,保证当前点文档中只有一个定时器在执行动画    if (element.timeId) {        clearInterval(element.timeId);        element.timeId = null;   } ​    // 2、div不停地向右移动    element.timeId = setInterval(function () { ​        //步进,开发中,不应该写死数据        var step = 3;        var current = element.offsetLeft; ​        // 3、div移动到指定的位置,停止移动        //如果等于500,就停止移动        if (element.offsetLeft >= target) {            clearInterval(element.timeId);            element.style.left = target + 'px';            return;       } ​        //累加步长        current += step;        element.style.left = current + 'px'; ​   }, frequency); } ​ ~~~ ### 完善动画 以上代码解决了一个页面总只能执行一个动画的问题。现在,新的问题又来了,当我们使用两个按钮控制一个div运动时,当点击"移动800"时,div正常地移动到了800的位置,此时当点击"移动400"时,div一瞬间跳回了400的位置,这就是问题了!当点击"移动400"时,我么需要的是div以动画方式缓缓地移动回400的位置。怎么实现这样的效果呢? **需求:**让div从800的位置缓缓移动到400的位置; **思路:**div在800的位置,当点击"移动400"时,只需将div的left从800慢慢递减到400,即可; html和css代码 ~~~ <style>    #box {        position: relative;        background-color: red;        width: 100px;        height: 100px;   }    #box2 {        position: relative;        background-color: blue;        width: 100px;        height: 100px;   } </style> ​ <input type="button" value="移动400" id="btn"> <input type="button" value="移动800" id="btn2"> <div id="box"></div> ​ ~~~ JavaScript代码 ~~~ //需求:让每一个元素记录一个定时器 ​ var btn = document.getElementById('btn'); var btn2 = document.getElementById('btn2'); var box = document.getElementById('box'); // var box2 = document.getElementById('box2'); ​ // 1、点击按钮,div向右移动 btn.onclick = function () {    animate(box, 400, 30); } ​ btn2.onclick = function () {    animate(box, 800, 30); } ​ ​ // var timeId = null; //封装动画代码到函数中 function animate(element, target, frequency){    //判断当前文档中是否已经启用定时器,如果启用,则先销毁,保证当前点文档中只有一个定时器在执行动画    if (element.timeId) {        clearInterval(element.timeId);        element.timeId = null;   } ​    // 2、div不停地向右移动    element.timeId = setInterval(function () { ​        //步长,开发中,不应该写死数据        var step = 10;        var current = element.offsetLeft; ​        //当当前位置 > 目标位置时, 步长 step 取负数        if(current > target){            step = -Math.abs(step);       } ​        // 3、div移动到指定的位置,停止移动        //当当前位置-目标位置 的绝对值小于或等于step的绝对值,则说明应该停止移动了        // Math.abs(current - target) <= Math.abs(step);        if (Math.abs(current - target) <= Math.abs(step)) {            clearInterval(element.timeId);            element.style.left = target + 'px';            return;       } ​        //累加步长        current += step;        element.style.left = current + 'px'; ​   }, frequency); } ~~~ ### 解决动画往回移动慢的问题 ~~~ 当div的left和offleft不同步或者并不相等时,会导致div从800移动到400时的速度很慢。此时需要在页面中加入样式 body { margin: 0; },将left的值和offset的值都是从0开始,这样就解决了问题。 ~~~ 最后我们得到的animate函数就是移动元素通用的函数了。所有我们可以将animate函数抽取到js文件中,以供将来重复调用。 ## 需求 ## 需求 注意,以下需求的代码实现在当天的项目中。 ### 无缝轮播图(掌握) ~~~ ================05_轮播图-动态生成序号================ 分析文档HTML和css结构,归纳出代码思路: 1、动态生成序号 2、点击序号,以动画的方式切换到相应图片 3、鼠标放到盒子上显示箭头 4、实现上一张和下一张的功能 5、自动切换图片 ​ 以下对思路进行代码实现: 1、动态生成序号 (1)获取页面上ul中的li个数,作为序号的个数,生成序号 (2)默认序号1高亮显示,两种方式 ​ ================06_轮播图-点击序号================ 2、点击序号,动画的方式切换到图片 问题:在li上注册点击事件,点击序号时,具体做什么? 2.1 取消其他li的高亮显示,让当前li高亮显示 2.2 点击序号,动画的方式切换到当前点击的图片 设置li的自定义属性,用于记录li的索引 获取自定义属性,移动的距离 = li的索引 * 图片宽度 注意:调用animate函数,移动的方向:往前是负数,往后是正数 ​ ================07_轮播图-显示箭头01================ 3、鼠标放到盒子上显示箭头 到此为止,我们好像做了很多分析,写了很多代码。我们把每个大的问题分解成了几个小问题,实际上每个小问题的解决所写的代码并不多。 ​ ==============08_轮播图-上一张和下一张=============== arrow:箭头 4、实现上一张和下一张的功能 思路一:当点击箭头时,获取当前选中的图片索引,索引+1并将图片切换一个图片的长度,此种做法可行,但是需要遍历获取到当前选中的li; 思路二:从索引为0的那张图片开始,每点击一次箭头,就调用一下animate做相应方向、大小的移动。 ​ 问题:无缝滚动问题比较复杂,先不做。 可以先采用这样的方式实现:当移动到最后一张图片时,再点击下一张箭头,图片不动 ​ 问题:图片切换之后,对应图片的序号没有高亮显示。 解决:使用click()方法触发当前元素的点击事件来完成点击,既解决图片切换问题,又解决序号高亮显示问题。 ​ ================11_轮播图-下一张无缝滚动================ 4、实现上一张和下一张的功能 刚开始接触这样的需求,如果没思路没关系,但是当我们分析了分析了之后,就要会独立去分析类似的问题,并解决问题。 无缝滚动实现方式: 页面加载完成时,复制第一张图片衔接到最后一张图片后面;此时,当点击下一张按钮时,将图片切换到最后一张图片上(也就是html中多复制出来的那一张),当再点击下一张时,将ul的外置瞬间改变成显示第1张图片的位置,然后切换到第2张图片。 ​ ================12_轮播图-上一张无缝滚动================ 当点击上一张按钮时,如果当前是第1张图片,此时要在一瞬间将第1张切换到最后一张图片的位置, ​ ================13_轮播图-自动播放================ 隔1秒切换到下一张,使用定时器完成。 思路:隔1秒中,点击(使用click方法)一下按钮; 问题:鼠标放到图片上时,没有停止滚动 解决:当鼠标放到图片上时,清除定时器;当鼠标移出图片时,启动定时器执行动画。 ​ ~~~ ### 回到顶部(掌握) ~~~ ================15_回到顶部01================ 以前:代码都是放到一个文件夹下,比较乱。 现在:把案例看做一下项目,文件分类,放到不同文件夹中,方便开发人员查找文件、维护代码。 ​ 1、当拖动滚动条时,当页面(内容)滚动出去10px的时候,改变top的高度,并显示回到顶部的按钮; ​ 问题:如何获取页面滚动出去的距离? document.body.scrollTop; documentElement 网页中的根元素html document.documentElement common中已经做了兼容性处理 ​ 注意:top是window对象中的只读属性,自定义名称不能为top,否则无法赋值 ​ 2、当点击回到顶部按钮时,动画的方式,回到最上面,让页面滚动距离为0; ​ ================16_回到顶部02================ 2、当点击回到顶部按钮时,动画的方式,回到最上面,让滚动距离为0; 使用简单动画的逻辑,参考animate()函数。 ​ ~~~