笔记目录
- 《智能社:JavaScript教程——从入门到精通》第1~5集笔记 事件
- 《智能社:JavaScript教程——从入门到精通》第6~10集笔记
- 《智能社:JavaScript教程——从入门到精通》第11~14集笔记 DOM操作和表格
- 《智能社:JavaScript教程——从入门到精通》第15~19集笔记 运动
- 《智能社:JavaScript教程——从入门到精通》第20~21集笔记 鼠标键盘事件
- 《智能社:JavaScript教程——从入门到精通》第22~23集笔记 事件高级应用
- 《智能社:JavaScript教程——从入门到精通》第24~25集笔记 Ajax
- 《智能社:JavaScript教程——从入门到精通》第26~29集笔记 面向对象
- 《智能社:JavaScript教程——从入门到精通》第30~31集笔记 坐标和cookie
- 《智能社:JavaScript教程——从入门到精通》第32集笔记 JS正则表达式
- 本文为原创,转载请注明:https://blog.xinpapa.com/2017/12/12/zhinengshe15-19/
详细内容
1.运动基础
- 让div动起来
- 速度——物体运动的快慢
- 运动中的bug
- 不会停止
- 速度取某些值会无法停止
- 到达位置后再点击还会运动
- 重复点击速度加快
- 匀速运动
- 速度不变
2.运动框架
- 例子1(网页的“分享到”侧边栏)如图:

代码如下:#div1{ width: 150px; height: 200px; background: #B3D4FC; position: absolute; left: -150px; } #div1 span{ position: absolute; width: 20px; height: 60px; line-height: 20px; background: gray; right: -20px; top: 70px; }<body> <div id="div1"> <span>分享到</span> </div> </body>window.onload = function () { var oDiv = document.getElementById("div1"); oDiv.onmouseover = function () { startMove(10, 0); }; oDiv.onmouseout = function () { startMove(-10, -150); }; }; var timer = null; function startMove(speed, iTarget) { var oDiv = document.getElementById("div1"); //先关闭定时器再开启,防止开启多个定时器 clearInterval(timer); timer = setInterval(function () { if (oDiv.offsetLeft == iTarget) { clearInterval(timer); } else { oDiv.style.left = oDiv.offsetLeft + speed + "px"; } }, 30); }; - 例子2(淡入淡出的图片)
代码如下:#div1{ width: 200px; height: 200px; background: red; filter: alpha(opacity:30); opacity: 0.3; }<body> <div id="div1"></div> </body>var alpha = 30;//alpha变量用于改变透明度 var timer = null; function startMove(iTarget) { var oDiv = document.getElementById("div1"); clearInterval(timer);//先关闭,避免开启多个定时器 timer = setInterval(function () { var speed = 0; if (alpha < iTarget) { speed = 10; } else { speed = -10; } if (alpha == iTarget) { clearInterval(timer); } else { alpha += speed; oDiv.style.filter = "alpha(opacity:" + alpha + ")"; oDiv.style.opacity = alpha / 100;//兼容火狐和chorme } }, 30); }; window.onload = function () { var oDiv = document.getElementById("div1"); oDiv.onmousemove = function () { startMove(100); }; oDiv.onmouseout = function () { startMove(30); }; };
3.缓冲运动
- 逐渐变慢,最后停止
- 距离越远速度越大
- 速度由距离决定
- 速度=(目标值-当前值)/缩放系数
- 例子:缓冲菜单
- bug:速度取整
- 跟随页面滚动的缓冲侧边栏
- 潜在问题:目标值不是整数时
- 代码如下(页面右侧悬浮框):
#div1{ width: 100px; height: 150px; background: red; position: absolute; right: 0; bottom: 0; }<body style="height: 2000px;"> <div id="div1"></div> </body>//元素滚动时执行 window.onscroll = function () { var oDiv = document.getElementById("div1"); var scrollTop = document.documentElement.scrollTop || document.body.scrollTop; startMove(parseInt((document.documentElement.clientHeight - oDiv.offsetHeight) / 2 + scrollTop)); }; var timer = null; function startMove(iTarget) { var oDiv = document.getElementById("div1"); clearInterval(timer); timer = setInterval(function () { var speed = (iTarget - oDiv.offsetTop) / 6; speed = speed > 0 ? Math.ceil(speed) : Math.floor(speed); if (oDiv.offsetTop == iTarget) { clearInterval(timer); } else { oDiv.style.top = oDiv.offsetTop + speed + "px"; } }, 30); };
4.多物体运动框架
- 例子:多个
div,鼠标移入变宽- 单定时器,存在问题
- 每个
div一个定时器
- 代码如下:
div{ width: 100px; height: 50px; background: red; margin: 10px; }<body> <div></div> <div></div> <div></div> </body>window.onload = function () { var aDiv = document.getElementsByTagName("div"); for (var i = 0; i < aDiv.length; i++) { aDiv[i].timer = null;//每一个div都加一个定时器 aDiv[i].onmouseover = function () { startMove(this, 400); }; aDiv[i].onmouseout = function () { startMove(this, 100); }; } }; function startMove(obj, iTarget) { clearInterval(obj.timer); obj.timer = setInterval(function () { var speed = (iTarget - obj.offsetWidth) / 6; speed = speed > 0 ? Math.ceil(speed) : Math.floor(speed); if (obj.offsetWidth == iTarget) { clearInterval(obj.timer); } else { obj.style.width = obj.offsetWidth + speed + "px"; } }, 30); }; - 多物体运动框架
- 定时器作为物体的属性
- 参数的传递:物体:目标值
- 例子:多个
div淡入淡出- 所有东西都不能公用
- 属性与运动对象绑定:速度、其他属性值(如透明度等)
- 代码如下:
div{ width: 200px; height: 200px; margin: 20px; float: left; background: red; filter: alpha(opacity:30); opacity: 0.3; }<body> <div></div> <div></div> <div></div> <div></div> </body>window.onload = function () { var aDiv = document.getElementsByTagName("div"); for (var i = 0; i < aDiv.length; i++) { aDiv[i].alpha = 30;//给每个div增加一个alpha属性 aDiv[i].onmouseover = function () { startMove(this, 100); }; aDiv[i].onmouseout = function () { startMove(this, 30); }; } }; //多物体运动框架的方法 function startMove(obj, iTarget) { clearInterval(obj.timer); obj.timer = setInterval(function () { var speed = (iTarget - obj.alpha) / 6; speed = speed > 0 ? Math.ceil(speed) : Math.floor(speed); if (obj.alpha == iTarget) { clearInterval(obj.timer); } else { obj.alpha += speed; obj.style.filter = "alpha(opacity:" + obj.alpha + ")"; obj.style.opacity = obj.alpha / 100; } }, 30); };
5.任意值运动框架
offset属性的bug- 用
offset时,让有边框的div变宽会出现bug - 解决方法是用
currentStyle代替offset
- 用
- 扩展运动矿井唉
- 运动属性作为参数
- 封装
opacity
- 代码如下:
div{ width: 200px; height: 200px; margin: 20px; float: left; background: red; border: 10px black solid; font-size: 16px; filter: alpha(opacity:30); opacity: 0.3; }<body> <div id="div1">变宽</div> <div id="div2">变高</div> <div id="div3">变字体大小</div> <div id="div4">变边框宽度</div> <div id="div5">变透明度</div> </body>window.onload = function () { var oDiv1 = document.getElementById("div1"); var oDiv2 = document.getElementById("div2"); var oDiv3 = document.getElementById("div3"); var oDiv4 = document.getElementById("div4"); var oDiv5 = document.getElementById("div5"); oDiv1.onmouseover = function () { startMove(this, "height", 400); }; oDiv1.onmouseout = function () { startMove(this, "height", 200); }; oDiv2.onmouseover = function () { startMove(this, "width", 400); }; oDiv2.onmouseout = function () { startMove(this, "width", 200); }; oDiv3.onmouseover = function () { startMove(this, "font-size", 30); }; oDiv3.onmouseout = function () { startMove(this, "font-size", 16); }; oDiv4.onmouseover = function () { startMove(this, "borderWidth", 50); }; oDiv4.onmouseout = function () { startMove(this, "borderWidth", 10); }; oDiv5.onmouseover = function () { startMove(this, "opacity", 100); }; oDiv5.onmouseout = function () { startMove(this, "opacity", 30); }; }; //多物体运动框架的方法 function startMove(obj, attr, iTarget) { clearInterval(obj.timer); obj.timer = setInterval(function () { var cur = 0; if (attr == "opacity") {//判断改变的是透明度还是其他属性 //round为四舍五入取整,解决计算失去精度的问题(比如0.07*100) cur = Math.round(parseFloat(getStyle(obj, attr)) * 100); } else { cur = parseInt(getStyle(obj, attr)); } var speed = (iTarget - cur) / 6; //三目运算用于判断是要向上取整还是向下取整 speed = speed > 0 ? Math.ceil(speed) : Math.floor(speed); if (cur == iTarget) {//如果是true,则停止定时器 clearInterval(obj.timer); } else { if (attr == "opacity") {//判断改变的是透明度还是其他属性 obj.style.filter = "alpha(opacity:" + (cur + speed) + ")"; obj.style.opacity = (cur + speed) / 100;//给火狐和chrome用 } else { obj.style[attr] = cur + speed + "px"; } } }, 30); }; function getStyle(obj, name) { if (obj.currentStyle) { return obj.currentStyle[name]; } else { return getComputedStyle(obj, null)[name]; } };
6.仿Flash图片展示1
- 让
div动起来偷懒了,没写
7.链式运动框架
- 用到回调函数
- 运动停止时,执行函数,开始下一次运动
- 例子代码如下:
#div1{ width: 100px; height: 100px; background: red; filter:alpha(opacity:30); opacity: 0.3; }<body> <div id="div1"></div> </body>window.onload = function () { var oDiv = document.getElementById("div1"); oDiv.onmouseover = function () { startMove(oDiv, "width", 400, function () { startMove(oDiv, "height", 400, function () { startMove(oDiv, "opacity", 100); }); }); }; oDiv.onmouseout = function () { startMove(oDiv, "opacity", 30, function () { startMove(oDiv, "height", 100, function () { startMove(oDiv, "width", 100); }); }); }; }; //多物体运动框架的方法 function startMove(obj, attr, iTarget, fnEnd) { clearInterval(obj.timer); obj.timer = setInterval(function () { var cur = 0; if (attr == "opacity") {//判断改变的是透明度还是其他属性 //round为四舍五入取整,解决计算失去精度的问题(比如0.07*100) cur = Math.round(parseFloat(getStyle(obj, attr)) * 100); } else { cur = parseInt(getStyle(obj, attr)); } var speed = (iTarget - cur) / 6; //三目运算用于判断是要向上取整还是向下取整 speed = speed > 0 ? Math.ceil(speed) : Math.floor(speed); if (cur == iTarget) {//如果是true,则停止定时器 clearInterval(obj.timer); if (fnEnd) { fnEnd();//回调函数 } } else { if (attr == "opacity") {//判断改变的是透明度还是其他属性 obj.style.filter = "alpha(opacity:" + (cur + speed) + ")"; obj.style.opacity = (cur + speed) / 100;//给火狐和chrome用 } else { obj.style[attr] = cur + speed + "px"; } } }, 30); }; function getStyle(obj, name) { if (obj.currentStyle) { return obj.currentStyle[name]; } else { return getComputedStyle(obj, null)[name]; } };
8.完美运动框架
- 多个值同时变化
- setStyle同时设置多个属性
- 参数传递:
json的使用、for in遍历属性
- 参数传递:
- 运动到运动框架
- 检测运动停止
- 标志变量
- setStyle同时设置多个属性
- 例子代码如下(伸缩的同时淡入淡出的菜单):
#div1{ width: 100px; height: 100px; background: red; filter: alpha(opacity:30); opacity: 0.3; }<body> <input id="btn1" type="button" value="运动" /> <div id="div1"></div> </body>window.onload = function () { var oBtn = document.getElementById("btn1"); var oDiv = document.getElementById("div1"); oBtn.onclick = function () { startMove(oDiv, {width: 103, height: 300, opacity: 100}); }; }; //完美运动框架的方法 function startMove(obj, json, fnEnd) { clearInterval(obj.timer); obj.timer = setInterval(function () { var stop = true;//假设所有的值都已经到了 for (var attr in json) { var cur = 0; if (attr == "opacity") {//判断改变的是透明度还是其他属性 //round为四舍五入取整,解决计算失去精度的问题(比如0.07*100) cur = Math.round(parseFloat(getStyle(obj, attr)) * 100); } else { cur = parseInt(getStyle(obj, attr)); } var speed = (json[attr] - cur) / 6; //三目运算用于判断是要向上取整还是向下取整 speed = speed > 0 ? Math.ceil(speed) : Math.floor(speed); //如果有任何一个运动没完成,则stop=false,不关闭定时器 if (cur != json[attr]) { stop = false; } if (attr == "opacity") {//判断改变的是透明度还是其他属性 obj.style.filter = "alpha(opacity:" + (cur + speed) + ")"; obj.style.opacity = (cur + speed) / 100;//给火狐和chrome用 } else { obj.style[attr] = cur + speed + "px"; } } if (stop) {//如果是true则所有运动都完成 clearInterval(obj.timer); if (fnEnd) { fnEnd();//回调函数 } } }, 30); };
9.运动框架总结
- 运动框架演变过程
startMove(iTarget):运动框架startMove(obj,iTarget):多物体运动框架startMove(obj,attr,iTarget):任意值运动框架startMove(obj,attr,iTarget,fn):链式运动框架startMove(obj,json,f):完美运动框架
- 例子(微博发布新信息效果):
#ul1{ margin: 10px auto; padding: 0; width: 400px; height: 400px; border: 1px black solid; overflow: hidden; } #ul1 li{ border-bottom: 1px #999 dashed; list-style: none; overflow: hidden; filter: alpha(opacity:0); opacity: 0; }<body> <textarea id="txt1" rows="4" cols="40"></textarea> <input id="btn1" type="button" value="发布" /> <ul id="ul1"> </ul> </body>window.onload = function () { var oBtn = document.getElementById("btn1"); var oUl = document.getElementById("ul1"); var oTxt = document.getElementById("txt1"); oBtn.onclick = function () { var oLi = document.createElement("li"); oLi.innerHTML = oTxt.value; oTxt.value = ""; if (oUl.children.length > 0) { oUl.insertBefore(oLi, oUl.children[0]); } else { oUl.appendChild(oLi); } //运动 var iHeight = oLi.offsetHeight; oLi.style.height = "0"; startMove(oLi, {height: iHeight}, function () { startMove(oLi, {opacity: 100}) }); }; }; //完美运动框架的方法 function startMove(obj, json, fnEnd) { clearInterval(obj.timer); obj.timer = setInterval(function () { var stop = true;//假设所有的值都已经到了 for (var attr in json) { var cur = 0; if (attr == "opacity") {//判断改变的是透明度还是其他属性 //round为四舍五入取整,解决计算失去精度的问题(比如0.07*100) cur = Math.round(parseFloat(getStyle(obj, attr)) * 100); } else { cur = parseInt(getStyle(obj, attr)); } var speed = (json[attr] - cur) / 6; //三目运算用于判断是要向上取整还是向下取整 speed = speed > 0 ? Math.ceil(speed) : Math.floor(speed); //如果有任何一个运动没完成,则stop=false,不关闭定时器 if (cur != json[attr]) { stop = false; } if (attr == "opacity") {//判断改变的是透明度还是其他属性 obj.style.filter = "alpha(opacity:" + (cur + speed) + ")"; obj.style.opacity = (cur + speed) / 100;//给火狐和chrome用 } else { obj.style[attr] = cur + speed + "px"; } } if (stop) {//如果是true则所有运动都完成 clearInterval(obj.timer); if (fnEnd) { fnEnd();//回调函数 } } }, 30); }; //得到样式属性的方法 function getStyle(obj, name) { if (obj.currentStyle) { return obj.currentStyle[name];//IE } else {//其他浏览器 return getComputedStyle(obj, null)[name]; } }