JavaScript进阶之--DOM事件、动画(运动框架)

来源:互联网 发布:怎么提高淘宝搜索权重 编辑:程序博客网 时间:2024/05/29 18:43

DOM事件

一、事件流

描述的是从页面中接收事件的顺序(当你点击一个容器里的子控件时,默认同时也点击了这个父容器)。

事件冒泡(ie):事件最开始由最具体的元素接收,然后逐级向上传播到最不具体的结点(子 -- 父 -- 祖父 --..--document )

事件捕获(ne):不具体的结点首先接收到事件,最具体的结点最后接收到,与冒泡相反


二、事件处理程序

1、HTML事件:直接在标签里添加的事件

<input id="btn" type="button" onclick="fun()" value="按钮"/>    //log()是定义在js中的一个函数

  缺点:HTML和JS代码紧密的耦合在一起

      2、DOM 0级事件:把一个函数赋值给一个事件 【ie】

var btn=document.getElementById('btn');btn.onclick = function(){//添加事件console.log('被点击了');}btn.onclick = null;//删除事件

      3、DOM 2级事件:定义了两个方法用于处理和删除事件 (chrome)

addEventListener( ...)、removeEventListener(event, listener, useCapture) :第一个参数 要处理的事件名、第二个参数事件处理的函数、第三个布尔值,表明事件是在冒泡阶段(false)还是捕获阶段(true)时调用    

btn.addEventListener("click", function(){console.log('addEvent被点击的');}, false);
btn.removeEventListener("click",fun,false);   //通过addEL添加的事件处理只能有removeEL删除

 4、IE 事件处理程序:添加 、删除事件 ( IE8之前只支持冒泡、欧普)

attachEvent( ...)、detachEvent(eventType, function) :第一个参数 事件处理名称、第二个 事件处理的函数

 

btn.attachEvent("onclick",log );     //注意是带 on 的

 

5、IE跨浏览器的事件处理程序:考虑兼容 ,需要封装一个对象方法

/** * 解决浏览器兼容 事件处理程序 * @param {[type]} element 事件源 * @param {[type]} type    事件处理类型(click/mouseover...) * @param {[type]} handler 处理事件 */function addHandler(element,type,handler){//如果支持DOM 2级事件处理程序if(element.addEventListener){element.addEventListener(type,handler,false);} else if(element.attachEvent){//支持IE 的事件处理程序  element.attachEvent('on'+type,handler);  } else{//支持DOM 0级  element['on'+type]= handler;    }}//移除事件function removeHandler(element,type,handler){//如果支持DOM 2级事件处理程序if(element.addEventListener){element.removeEventListener(type,handler);} else if(element.attachEvent){//支持IE 的事件处理程序  element.detachEvent('on'+type,handler);  } else{//支持DOM 0级  element['on'+type]= null;    }}//调用方法addHandler(btn4,'click',fun);removeHandler(btn4,'click',fun);

三、事件对象

触发DOM上事件产生的对象

1、DOM中的事件对象event ( 调用 :  event.type )  ---IE无用

    1)type :事件类型( click )

   2)target :事件目标( 事件源)

 3)stopPropagation():阻止事件冒泡

 4)preventDefault(): 阻止事件的默认行为 (a标签的跳转页面)

2、IE中的事件对象( window.event )

在使用event时要先做一个兼容性:var event= event || window.event;

1)type :事件类型( click )

2) srcElement:事件源  【IE8获取得到的类型是object】

3) cancelBubble:阻止事件冒泡(这是一个属性,true为阻止冒泡)

4) returnValue:阻止默认事件(false表示阻止事件默认行为)

3、封装方法解决兼容性

//封装事件方法的对象var eventUtil={//获取事件对象getEvent:function(event){return  event|| window.event;//兼容IE},//获取事件对象类型getType:function (event){return event.type;},//事件源getTarget:function (event){return event.target || event.srcElement;},//阻止事件冒泡stopPropagation:function (event){if(event.stopPropagation){event.stopPropagation();} else{//IE事件 event.cancelBubble=true;  }},//阻止默认行为preventDefault:function (event){if(event.preventDefault){event.preventDefault();}  else{//IE事件  event.returnValue=false;  }}}


四、事件类型

1、键盘事件
keyDown:按下键盘上的任意键触发,按住不放则重复触发
keyPress:按下键盘上的字符键触发,按住不放则重复触发
keyUp:释放键盘上的键时触发

keyCode:根据键盘码确定按下的键,从event中获取
document.keyUp=function(event){ var event=event || window.event;  console.log(event.keyCode); }

动画

一、速度动画

/** * 实现对象的左右移动 * @param  {[type]} obj    目标对象 * @param  {[type]} target 移动终点 * @param  {[type]} speed  移动速度 * @return {[type]}        无返回 */function move(obj,target,speed){clearInterval(obj.timer);//清空计时器,obj.timer=setInterval(function(){//自定义定时器var left=obj.offsetLeft;//number 数值if(left>target){//当前位置在目标值的右边,则速度为负speed=speed <0 ? speed:-speed;//速度值,保持为负数console.log('speed'+speed);} //如果移动的某一时间段在一定的范围内,则直接设为目标值if( Math.abs( Math.abs(left)-Math.abs(target) ) < Math.abs(speed)  ){obj.style.left=target+'px';//达到目标值console.log('=='+left);clearInterval(obj.timer);} else{left+=speed;//移动obj.style.left=left+'px';console.log('left'+left);}},50);}

二、透明度动画

<!-- 样式-->div{width: 200px;height: 200px;background-color: blue;filter:alpha(opacity:10);/*滤镜效果*/opacity:0.1;}
var alpha=10;//先获取opacity的值/*** 改变透明度的动画 ---要先取得当前对象的opacity(透明度)* @param  {[type]} obj    目标对象* @param  {[type]} target 目标透明度值  0-1* @param  {[type]} speed  变化速度  1-100* @return {[type]}        无返回值*/function changeOpacity(obj,target,speed){clearInterval(obj.timer);//清除obj.timer=setInterval(function(){//自定义的定时器var current=alpha/100;//当前透明度0-1if(current>target){    //当前透明度更低,更不透明(越接近1)speed=speed <0 ? speed:-speed;//速度值,保持为负数console.log('speed'+speed);} //如果透明度的变化将达到目标值,则直接设为目标值if( Math.abs( Math.abs(current)-Math.abs(target) ) < Math.abs(speed/100)  ){obj.style.filter='alpha(opacity:'+target*100+')';//达到目标值obj.style.opacity=target;//设为目标值clearInterval(obj.timer);}  else{alpha+=speed;//改变透明度  0-100console.log("alpha"+alpha);obj.style.filter='alpha(opacity:'+alpha+')';obj.style.opacity=alpha/100;//设置透明度属性  }},50);}


//解决多物体同时运行的冲突

obj.alpha=10;   //通过自定义属性的方式获取到透明度的值




三、缓冲动画

/** * 缓冲运动,速度是逐渐变小 * @param  {[type]} obj    目标对象 * @param  {[type]} target 移动终点 * @param  {[type]} speed  移动速度(可不传参 * @return {[type]}        无返回 */function move(obj,target,speed){clearInterval(obj.timer);//清空计时器,obj.timer=setInterval(function(){//自定义定时器var left=obj.offsetLeft;//number 数值speed=(target-left)/10;console.log("speed1::"+speed);speed= speed > 0 ? Math.ceil(speed) : Math.floor(speed);//解决小数【注意是向上/向下取整console.log("speed2::"+speed);//如果移动的某一时间段在一定的范围内,则直接设为目标值if(left==target){//达到目标值clearInterval(obj.timer);} else{obj.style.left=left+speed+'px'; }},50);}


四、自定义属性的动画

获取样式:作用请看来源(当变化宽高,而设定css样式时有border属性,最后变化是不一样的 )

/** * 获取对象的样式 * @param  {[type]} obj  目标对象 * @param  {[type]} attr 样式参数 * @return {[type]}      对应的样式值 */function getStyle(obj,attr){console.log(typeof attr);if(obj.currentStyle){return obj.currentStyle[attr];//ie浏览器}  else { return getComputedStyle(obj,false)[attr];//火狐  }}//调用:console.log(getStyle(box,'width')); 
/** * 自定义属性的动画,改变样式【宽高等单位为px的属性】 * @param  {[type]} obj    目标对象 * @param  {[type]} target 变化结果 * @param  {[type]} attr   变化的属性 */function move(obj,target,attr){clearInterval(obj.timer);//清空计时器,obj.timer=setInterval(function(){//自定义定时器var myStyle=parseInt( getStyle(obj,attr) ); //获取当前属性值,并转化为numberconsole.log(myStyle);var speed=(target-myStyle)/10;speed= speed > 0 ? Math.ceil(speed) : Math.floor(speed);if(myStyle==target){//达到目标值clearInterval(obj.timer);} else{obj.style[attr] = myStyle+speed+'px'; }},50);}
//透明度属性//传参数时,透明度为0-100,对应0-1if(attr==='opacity'){//判断是否为透明度var myStyle=parseFloat( getStyle(obj,'opacity') )*100 ;//小数myStyle=Math.round(myStyle); //四舍五入解决不精确}if(attr==='opacity'){obj.style.filter='alpha(opacity:'+myStyle+speed+')';//设置透明度obj.style[attr]=(myStyle+speed)/100 ;

五、链式动画(连续动画)

增加函数参数,当执行完动画后,调用了此回调函数,再次进行动画

function move(obj,target,attr,fun){....if(myStyle==target){//达到目标值clearInterval(obj.timer);if(fun){//判断是否有值fun();  //设为并执行函数}}}
box.onmouseover=function(){move(box,100,'opacity',function(){//回调函数move(box,100,'width',400);});


五、完成动画--运动框架--实现多物体同时进行 多动画


运动框架--速度动画*{margin: 0;padding: 0;}div{width: 200px;height: 200px;background-color: blue;filter:alpha(opacity:10);opacity: 0.1;}#box2{background-color: #000;}