Day16
Day16
1-什么是事件委托,原理是什么?
2-js 中有几种定时器,有什么区别?
3-如何清除定时器?
4-封装一个动画函数
1-什么是事件委托,原理是什么?
JS事件代理就是通过给父级元素(例如:ul,tr等等)绑定事件,不给子级元素(例如:li,td等等)绑定事件,然后当点击子级元素时,
通过事件冒泡机制在其绑定的父元素上触发事件处理函数,主要目的是为了提升性能,因为我不用给每个子级元素绑定事件,只给父级元素绑定一次就好了,在原生js里面就是通过event对象的taget属性实现。
var ul=document.querySelector("ul"); ul.onclick=function(e){ //e这里指event对象 var target=e.target=e.target||e.srcElement;//target 获取触发事件的目标(li) if(target.nodeName.toLowerCase()==' li '){ //目标(li)节点名转小写字母,不转换的话是大写字母 alert(target.innerHTML) } } jq方式实现相对而言简单 $('ul').on('click','li',function(){ //事件逻辑 }) 其中第二个参数指的是触发事件的具体目标,特别是给动态添加的元素添加事件。
2-js 中有几种定时器,有什么区别?
setTimeout只在指定时间后执行一次,代码如下: <script> //定时器 异步运行 function hello(){ alert("hello"); } //使用方法名字执行方法 var t1 = window.setTimeout(hello,1000); var t2 = window.setTimeout("hello()",3000);//使用字符串执行方法 window.clearTimeout(t1);//去掉定时器 </script>
setInterval以指定时间为周期循环执行,代码如下: //实时刷新时间单位为毫秒 setInterval('refreshQuery()',8000); /* 刷新查询 */ function refreshQuery(){ $("#mainTable").datagrid('reload',null); }
3-如何清除定时器?
如上题
//清除Timeout的定时器,
传入id(创建定时器时会返回一个id) clearTimeout(i);
//清除Interval的定时器,
传入id(创建定时器时会返回一个id) clearInterval(j);
例子
// window.setInterval(code,millisec); var i = 0; //设置定时器(循环去执行) var timeId = setInterval(function () { i++; console.log('定时运行:' + i + '次') }, 500) //清理定时器 my$('btn').onclick = function () { window.clearInterval(timeId) } //window.setTimeout(code,millisec); var i = 0; //设置定时器(一次性定时器) var timeId = setTimeout(function () { i++; console.log('定时运行:' + i + '次') }, 500) //清理定时器(这个定时器虽然只有一次,但是也得清理 既可以释放内存,也可以便于后边代码的判断。) my$('btn').onclick = function () { window.clearTimeout(timeId) }
4-封装一个动画函数
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>JS动画demo与函数封装</title> <style> .parent{ width: 300px;height: 300px; background: gray; position: relative; } .son{ position: absolute; width: 50px; height: 50px; background: rgb(100, 100,180); } </style> </head> <body> <div class = "parent"> <div class="son"> </div> </div> <script> window.onload = function(){ var parent = document.getElementsByClassName("parent")[0]; var son = document.getElementsByClassName("son")[0]; parent.addEventListener("mouseover",function(){ animate(son, { "left": 100 }, function () { }); },false); parent.onmouseleave = function () { animate(son, { "left":0 }, function () { }); } } </script> <script> // 获取当前制定样式的属性值 function getStyle(ele,attr){ if(window.getComputedStyle){ //兼容性检测,优先采用W3C标准 return window.getComputedStyle(ele,null)[attr]; }else{ return ele.currentStyle[attr]; //兼容Ie低版本浏览器 } } /* * 缓动动画函数 * 原理:盒子原本的样式值 + "步长"(不断变化的值);达到目标值后停止缓动。 * ele:指定的节点对象 * attr_json:样式属性和值的集合(json对象格式,如{"width":200,"left":10}) * callback:回调函数,动画执行完后执行的函数 * 注意:如果控制 盒子的透明度 在本函数json属性集合中需要使用opacity,控制层级需要使用zIndex * */ function animate(ele,attr_json,callback){ // 清除定时器,避免动画重合 clearInterval(ele.timer); ele.timer = setInterval(function(){ var flag = true; //定时器是否清除的标记值 for(var attr in attr_json){ var current = 0; //获取当前样式 if(attr == "opacity"){ //如果是透明度,那么返回值,如果不兼容就返回0 current = Math.round(parseInt(getStyle(ele,attr)*100))||0; }else{ //其他 current = parseInt(getStyle(ele,attr)); } //计算步长,并进行取整来避免除不尽引起的误差 var stepLength = (attr_json[attr] - current)/10; stepLength = stepLength > 0?Math.ceil(stepLength):Math.floor(stepLength); //判断要改变的样式是否是透明度 if(attr == "opacity"){ if("opacity" in ele.style){ ele.style.opacity = (current+stepLength)/100; }else{ ele.style.filter = "alpha(opacity = " + (current+stepLength)*10+")"; } } //判断要改变的样式是否是层级 else if(attr == "zIndex"){ ele.style.zIndex = current+stepLength; } //其他属性 else{ ele.style[attr] = (current + stepLength) + "px"; } //判断是否清除定时器 if(current != attr_json[attr]){ flag = false; } } if(flag){ clearInterval(ele.timer); if(callback){ callback(); } } },10) } </script> </body> </html>