事件
用户交互行为,用户或浏览器自身执行的某种动作
事件流
页面接收事件的顺序,事件触发的顺序,
分为 事件冒泡(子级先触发,冒泡到父级)和事件捕获(父级先触发,再到达子级) 先捕获->处于目标阶段 -> 再冒泡
- 事件冒泡:事件按照从最特定的事件目标到最不特定的事件目标(document对象)的顺序触发,子级元素先触发
- 事件捕获:事件从最不精确的对象(document对象)开始触发,然后到最精确(也可以在窗口级别捕获事件,不过必须由开发人员特别指定),父级元素先触发
- 事件捕获阶段:事件从最上一级标签开始往下查找,直到捕获到事件目标(target)。
- 事件冒泡阶段:事件从事件目标(target)开始,往上冒泡直到页面的最上一级标
事件模型的各个阶段
捕获阶段-目标阶段-冒泡阶段
事件处理程序
响应某个事件的函数
- HTML(在标签内嵌入事件)
- DOM0(通过DOM操作,给节点上添加事件)
- DOM2(addEventlistener(‘click’, fn, false))
- IE(attachEvent(‘onclick’, fn))
- 跨浏览器(EventUtil函数)
// 跨浏览器处理 综上,兼容DOM和IE的不同处理,
var EventUtil = {
// 跨浏览器 前两个是兼容 事件对象,中间两个是兼容 事件冒泡或默认行为 ,后两个是兼容 事件处理程序
getEvent: function(event){
return event ? event : window.event;
},
getTarget: function(event){
return event ? event.target : event.srcElement;
},
stopPropagation: function(event){
if(event){
return event.stopPropagation();
} else {
return event.cancelBubble = true;
}
},
preventDefault: function(event){
if(event){
return event.preventDefault();
} else {
return event.returnValue = false;
}
},
addHandler: function(element, type, handler){
if(element.addEventListener) {
return element.addEventListener(type, handler, false) // DOM2
} else if(element.attachEvent) {
return element.attachEvent("on"+type, handler) // IE
} else {
return element["on"+type] = handler // DOM0
}
},
removeHandler: function(element, type, handler){
if(element.removeEventListener) {
return element.removeEventListener(type, handler, false) // DOM2
} else if(element.detachEvent) {
return element.detachEvent("on"+type, handler) // IE
} else {
return element["on"+type] = null // DOM0
}
}
}
事件对象
触发事件 event 对象的所有信息
DOM事件模型中的事件对象常用属性:
- type用于获取事件类型
- target获取事件目标
- stopPropagation()阻止事件冒泡
- preventDefault()阻止事件默认行为
IE事件模型中的事件对象常用属性:
- type用于获取事件类型
- srcElement获取事件目标
- cancelBubble = true 阻止事件冒泡
- returnValue = false 阻止事件默认行为
W3C模型是将两者进行中和,在W3C模型中,任何事件发生时,先从顶层开始进行事件捕获,直到事件触发到达了事件源元素。然后,再从事件源往上进行事件冒泡,直到到达document。
IE只支持事件冒泡,不支持事件捕获,它也不支持addEventListener函数,不会用第三个参数来表示是冒泡还是捕获,它提供了另一个函数attachEvent。
ele.attachEvent(“onclick”, doSomething2);
使用jquery,既停止冒泡又阻止默认行为
$("#testC").on('click',function(){
return false;
});
ele.addEventListener(‘click’,doSomething2,true)
true=捕获 false=冒泡
事件类型
- UI(User Interface,用户界面)事件,当用户与页面上的元素交互时触发; 如resize,scroll
- 焦点事件,当元素获得或失去焦点时触发; 如blur (在元素失去焦点时触发,这个事件不会冒泡)
- 鼠标事件,当用户通过鼠标在页面上执行操作时触发;如click
- 滚轮事件,当使用鼠标滚轮(或类似设备)时触发;
- 文本事件,当在文档中输入文本时触发;
- 键盘事件,当用户通过键盘在页面上执行操作时触发;
- 合成事件,当为 IME(Input Method Editor,输入法编辑器)输入字符时触发;
- 变动(mutation)事件,当底层 DOM 结构发生变化时触发。
事件委托
事件委托就是利用事件冒泡,只指定一个事件处理程序,就可以管理某一类型的所有事件
减少与dom交互,提高性能
页面上有这么一个节点树,div>ul>li>a;比如给最里面的a加一个click点击事件,那么这个事件就会一层一层的往外执行,执行顺序a>li>ul>div,有这样一个机制,那么我们给最外面的div加点击事件,那么里面的ul,li,a做点击事件的时候,都会冒泡到最外层的div上,所以都会触发,这就是事件委托,委托它们父级代为执行事件
xs.on事件=function(){} //相当于写一个函数。
处理兼容性问题
var ev = ev || window.event;
var target = ev.target || ev.srcElement;
window.onload = function(){
var Oul = document.getElementById('oul');
//var Oul = document.getElementsByTagName('ul');
//想要使用addEventListener,必须是dom元素,获取的是id值
Oul.addEventListener('click',function(ev){
var ev = ev || window.event;
var target = ev.target || ev.srcElement;
//不能直接使用target,必须有所转换再去匹配
if(target.nodeName.toLowerCase() == "li"){
alert(target.innerHTML);
}
},false);
// Oul.οnclick= function(){
// alert('aaa')
// }
}
跨浏览器实现:
<ul id="weituo">
<li>子节点1</li>
<li>子节点2</li>
<li>子节点3</li>
</ul>
var ww = document.getElementById("weituo");
var handleee = function(e){
var event = EventUtil.getEvent(e);
var target = EventUtil.getTarget(e);
// 判断是否匹配目标元素
console.log(target.nodeName);
if (target.nodeName.toLocaleLowerCase() === 'li') {
console.log('the content is: ', target.innerHTML);
}
}
EventUtil.addHandler(ww, "click", handleee)