JavaScript事件理解

1、事件流

当单击页面上的一个按钮时,实际上也相当于单击了按钮的button的父容器,也单击了body,甚至也单击了整个页面。

事件流描述了从页面接受事件的顺序。

事件流有两种:事件冒泡、事件捕获

 

例:

<html>
<head></head>
<body>
    <div>
        <button>Click</button>
    </div>
</body>
</html>

事件冒泡:button->div->body->html->document

事件捕获:document->html->body->div->button

 

一般现在浏览器都使用事件冒泡,有特殊需求时用事件捕获。

 

2、DOM事件流

事件流包括三个阶段:事件捕获阶段、目标作用阶段、事件冒泡阶段

事件捕获阶段:document->html->body->div

目标作用阶段:button.onclick = ...

事件冒泡阶段:div->body->html->document

 

3、事件处理程序

DOM0级事件处理:

为element绑定事件:element.onclick = function(){...}

为element取消绑定:element.onclick = null;

 

DOM2级事件处理:

为element添加事件(其中第一个参数为事件名,第二个参数为触发事件,第三个参数为true代表事件捕获阶段触发,false代表事件冒泡阶段触发):

element.addEventListener("click",myFunc1,false);

element.addEventListener("click",myFunc2,false);  //触发顺序与添加顺序相同

为element取消事件():

element.removeEventListener("click",myFun1,false)

注意添加时间时:如果传入匿名函数function(){...}将无法删除,毕竟匿名,没名字怎么删

 

4、IE8及更早的版本,可以用attachEvent()与detachEvent()添加删除事件

用法element.attachEvent("onclick",myfunc1);  //注意传入的第一个参数是onclick不是click,且只支持冒泡触发

 

兼容的实现

var EventUtil = {
	addHandler: function(element, type, handler){
		if (element.addEventListener){
			element.addEventListener(type,handler,false);
		} else if (element.attachEvent){
			element.attachEvent(type,handler);
		} else {
			element["on" + type] = handler;
		}
	},
	removeHandler: function(element, type, handler){
		if (element.removeEventListener){
			element.removeEventListener(type,handler,false);
		} else if (element.detachEvent){
			element.detachEvent(type,handler);
		} else {
			element["on" + type] = null;
		}
	}
}

 

5、事件对象

出发DOM上某个事件时,会产生一个事件对象event,包含于该事件相关的信息,

包括事件绑定元素、事件类型等,与鼠标相关的事件包含鼠标的坐标的,与键盘相关的事件会包含按下按键的键码等

element.onclick = function(event){

  alert(event.type);  //"click"

}

element.addEventListener("click",function(event),false){

  alert(event.type)  //"click"

}

除了event.type,常用方法属性还有

取消事件默认行为:preventDefault()

阻止事件冒泡:stopPropagation()

事件绑定的对象:target

 

IE中的事件对象,不需要传入event对象,event对象是window的一个属性

element.onclick = function(){

  var event = window.event;

  alert(event.type);  //"click"

}

取消事件默认行为:returnValue = faslse;

阻止事件冒泡:cancelBubble = true;

事件绑定的对象:srcElement

 

兼容的实现:

var EventUtil = {
	addHandler: function(element, type, handler){
		if (element.addEventListener){
			element.addEventListener(type,handler,false);
		} else if (element.attachEvent){
			element.attachEvent(type,handler);
		} else {
			element["on" + type] = handler;
		}
	},

	getEvent: function(event){
		return event ? event : window.event;
	},

	getTarget: function(event){
		return event.target || event.srcElement;
	},

	preventDefault: function(event){
		if (event.preventDefault){
			event.preventDefault();
		}
		else{
			event.returnValue = false;
		}
	},

	removeHandler: function(element, type, handler){
		if (element.removeEventListener){
			element.removeEventListener(type,handler,false);
		} else if (element.detachEvent){
			element.detachEvent(type,handler);
		} else {
			element["on" + type] = null;
		}
	},

	stopPropagation: function(event){
		if (event.stopPropagation){
			event.stopPropagation();
		}
		else{
			event.cancelBubble = true;
		}
	}
}

 

6、性能与内存

函数就是对象,绑定越多的事件处理函数,内存开销越大,同时访问DOM的次数变多,页面交互事件延长

事件委托:

例:

<ul id="myUl">
    <li id="myLi1">新闻</li>
    <li id="myLi2">体育</li>
    <li id="myLi3">财经</li>
</ul>

为上述三个列表项添加单击事件,常规的做法是为每一个添加一个单击事件,显然这是低效的

使用事件委托,在DOM数中尽可能高的层次添加时间处理程序,识别到底是哪个子元素是当前操作的元素,

并触发它的事件。

var myUL = document.getElementById("myUl");

EventUtil.addEvent(myUL,"click",function(event){
  var event = EventUtil.getEvent(event);
  var target = EventUtil.getTarget(event);

  switch(target.id){

    case "myLi1":
      //do something
      break;
    case "myLi2":
          //do something
      break;
    case "myLi3":
          //do something
      break;
  }
}) ;

  

转载于:https://www.cnblogs.com/olafff/p/5145524.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值