知识点:
-事件流
-事件注册
-事件对象
-事件分类
-事件代理
什么是DOM事件?
-点击一个DOM元素
-键盘按下一个键
-输入框输入内容
-页面加载完成
一、事件流
DOM处理事件的过程。
当点击<a>标签时的事件流:
1、从window-》document-》<html>-》<body>-》<div>-》<p> capture phase 捕获阶段
2、<p>-》<a> <a>----》<p> target phase
3、<p>-》<div>-》<body>-》<html>-》<document>-》<window> bubble phase冒泡阶段(页面load是没有这个过程的)
二、事件注册
1、事件注册
eventTarget.addEventListener(type,listener[,useCapture]) 作用于一个DOM对象的,接收三个参数:事件类型、事件处理函数、是否为捕获过程。默认处理的是冒泡过程,只有把useCapture设置为true时,才处理捕获过程。
var elem = document.getElementById('div1');
var clickHandler = function(event){
//TODO
}
elem.addEventListener('click', clickHandler, false);
还有一种注册方式:elem.onclick = clickHandler;
这种方式有一个缺点:只能注册一个事件处理函数。
2、取消事件注册
eventTarget.removeEventListener(type, listener[,useCapture])
elem.removeEventListener('click', clickHandler, false);
elem.onclick = null;
3、事件触发
使用程序代码来触发:
eventTarget.dispatchEvent(type)
elem.dispatchEvent('click');
4、浏览器兼容型(IE6、7、8)
-事件注册与取消:
attachEvent / detachEvent
-事件触发:
fireEvent(e)
-没有捕获阶段(no capture)
var addEvent = document.addEventListener ? function(elem, type, listener, useCapture){
elem.addEventListener(type, listener, useCapture);
} : function(elem, type, listener, useCapture){
elem.attachEvent('on' + type, listener);
};
var delEvent = document.removeEventListener ? function(elem, type, listener, useCapture){
elem.removeEventListener(type, listener, useCapture);
} : function(elem, type, listener, useCapture){
elem.detachEvent('on' + type, listener);
};
三、事件对象
事件的主体。当事件被触发时会调用事件处理函数,调用时需要传入一些信息,这些信息就构成了事件对象。
-属性
type
target(srcElement)
currentTarget
-方法
stopPropagation 阻止事件传播(阻止冒泡)
preventDefault 阻止默认行为
stopImmediatePropagation 阻止冒泡
1、阻止事件传播
event.stopPropagation() (W3C)
event.cancelBubble = true (IE)
event.stopImmediatePropagation() (W3C) 与第一个方法的区别:做了两件事情:①阻止事件传播到父节点②阻止当前节点的后续事件。
2、默认行为
比如:点击链接时链接会被打开,双击一段文字,文字会被选中等。
阻止默认行为:
Event.preventDefault() (W3C)
Event.returnValue = false (IE)
四、事件分类
1、鼠标事件
①MouseEvent对象
-属性
clientX(鼠标触发时,鼠标在页面上的位置到页面的最左端的距离),clientY(鼠标触发时,鼠标在页面上的位置到页面最上端的距离)
screenX,screenY(鼠标在页面上的位置到屏幕最左/顶端的距离)
ctrlKey,shiftKey,altKey,metaKey(当相应的键盘键被按下是值为true)
button(0,1,2)(鼠标被按下的左中右键)
②MouseEvent顺序
示例:从元素A上方移过
-mousemove------》mouseover(A)------》mouseenter(A)-------》mousemove(A)-------》mouseout(A)------》mouseleave(A)
点击元素
-mousedown------》[mousemove]-------》mouseup-------》click
例子:拖拽div
HTML:
<div id="div1"></div>
CSS:#div1{
position:absolute;
top:0;
left:0;
border:1px solid #000;
width:100px;
height:100px;
}
JS:var elem = document.getElementById("div1");
var clientX,clientY,moving;
var mouseDownHandler = function(event){
event = event || window.event;
clientX = event.clientX;
clientY = event.clientY;
moving = !0;
}
var mouseMoveHandler = function(event){
if(!moving) return;
event = event || window.event;
var newClientX = event.clientX, newClientY = event.clientY;
var left = parseInt(elem.style.left) || 0, top = parseInt(elem.style.top) || 0;
elem.style.left = left + (newClientX - clientX) + 'px';
elem.style.top = top + (newClientY - clientY) + 'px';
clientX = newClientX;
clientY = newClientY;
}
var mouseUpHandler = function(event){
moving = !1;
}
addEvent(elem, 'mousedown', mouseDownHandler);
addEvent(elem, 'mousemove', mouseMoveHandler);
addEvent(elem, 'mouseup', mouseUpHandler);
代码还需完善,这里还应该设置元素不能被选中,拖动不能超过的范围等。
③WheelEvent对象
-属性:
deltaMode
deltaX
deltaY
deltaZ
2、键盘、输入、焦点事件
①FocusEvent
-属性:
relatedTarget
②InputEvent
③KeyboardEvent
-属性:
key 值为字符串
code 值为字符串
ctrlKey、shiftKey、altKey、metaKey 值为布尔值
repeat 当一个键被一直被按着时,值为true
keyCode
charCode
which
window:
-load
-unload
-error
-abort
Image:
-load
-error
-abort
<img alt="photo" src="http://www.163.com/photo.jpg" onerror="this.src='http://www.163.com/default.jpg'" />
五、事件代理
案例:网易云音乐的歌曲列表
点击歌曲时该歌曲的背景色变为深色
分析:创建一个ul列表,给下面的每一个li添加事件
<ul id="myUl">
<li></li>
<li></li>
</ul>
<script>
var myUl = document.document.getElementById('myUl');
var myLis = myUl.getElementsByTagName('li');
myLis[0].addEventListener('click',function(){
//TODO
});
myLis[1].addEventListener('click',function(){
//TODO
});
</script>
从事件冒泡来看,可以将事件注册到元素的父元素上,也是会执行的。——将事件注册到ul上。
事件代理的处理方法:
-将事件注册到元素的父节点上
<ul id="myUl">
<li></li>
<li></li>
</ul>
<script>
var myUl = document.document.getElementById('myUl');
myUl.addEventListener('click', function(event){
var e = event || window.event;
var target = e.target || e.srcElement;
//TODO
});
</script>
事件代理的优缺点:
优点:
-需要管理的handler更少
-内存分配更少
-增加 / 删除节点可以不处理事件
缺点:
-事件管理的逻辑更复杂(判断哪些是需要处理的,哪些是不需要处理的)